Sun, 10 Sep 2023 12:52:10 +0200
some more code cleanup
--- a/src/main/java/de/unixwork/uwproj/Define.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Define.java Sun Sep 10 12:52:10 2023 +0200 @@ -1,13 +1,9 @@ package de.unixwork.uwproj; public class Define { - private String name; - private String value; + private final String name; + private final String value; - public Define() { - - } - public Define(String name, String value) { this.name = name; this.value = value; @@ -17,17 +13,9 @@ return name; } - public void setName(String name) { - this.name = name; - } - public String getValue() { return value; } - - public void setValue(String value) { - this.value = value; - } public String toFlags() { if(name == null) {
--- a/src/main/java/de/unixwork/uwproj/Dependency.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Dependency.java Sun Sep 10 12:52:10 2023 +0200 @@ -21,8 +21,6 @@ private final List<String> lang = new LinkedList<>(); - private boolean abortOnError = false; - private int num = 0; public static Dependency parse(Element element) throws Exception { @@ -116,14 +114,6 @@ this.pkgconfig.add(pkgconfig); } - public boolean isAbortOnError() { - return abortOnError; - } - - public void setAbortOnError(boolean abortOnError) { - this.abortOnError = abortOnError; - } - public int getNum() { return num; }
--- a/src/main/java/de/unixwork/uwproj/Feature.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Feature.java Sun Sep 10 12:52:10 2023 +0200 @@ -4,42 +4,44 @@ import java.util.List; +import static de.unixwork.uwproj.Util.isNotNullOrBlank; + public class Feature { private String name; private String arg; private boolean def; - + private TargetData targetData; - + public static Feature parse(Project project, Element e) throws Exception { Feature feature = new Feature(); String name = e.getAttribute("name"); String arg = e.getAttribute("arg"); String def = e.getAttribute("default"); - - if(name.isEmpty()) { + + if (name.isBlank()) { throw new Exception("feature element requires name attribute"); } - + String ld = def.toLowerCase(); boolean on = ld.equals("on") || ld.equals("true"); feature.setName(name); feature.setDefault(on); - if(arg.isEmpty()) { + if (arg.isBlank()) { feature.setArg(name); } else { feature.setArg(arg); } - + feature.setTargetData(TargetData.parse(e)); project.addFeature(feature); return feature; } - + public String getVarName() { - return "FEATURE_"+name.toUpperCase(); + return "FEATURE_" + name.toUpperCase(); } - + public List<String> getDependencies() { return getTargetData().getDependencies(); } @@ -47,13 +49,13 @@ public List<Define> getDefines() { return getTargetData().getDefines(); } - + public String getMake() { return targetData.getMake(); } - + public boolean hasMake() { - return !targetData.getMake().trim().isEmpty(); + return isNotNullOrBlank(targetData.getMake()); } public String getName() { @@ -86,5 +88,5 @@ public void setTargetData(TargetData targetData) { this.targetData = targetData; - } + } }
--- a/src/main/java/de/unixwork/uwproj/Option.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Option.java Sun Sep 10 12:52:10 2023 +0200 @@ -6,45 +6,47 @@ import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; + +import static de.unixwork.uwproj.Util.shId; public class Option { private String arg; - - LinkedList<OptionValue> values = new LinkedList<>(); - LinkedList<OptionDefault> defaults = new LinkedList<>(); - - public static Option parse(Project project, Element element) throws Exception { - Option opt = new Option(); + + private final LinkedList<OptionValue> values = new LinkedList<>(); + private final LinkedList<OptionDefault> defaults = new LinkedList<>(); + + public static Option parse(Element element) throws Exception { + var opt = new Option(); String arg = element.getAttribute("arg"); - if(arg.isEmpty()) { + if (arg.isBlank()) { throw new Exception("Option has no argument string"); } opt.setArgument(arg); - + NodeList nodes = element.getChildNodes(); - for(int i=0;i<nodes.getLength();i++) { + for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { - Element elm = (Element)node; + Element elm = (Element) node; String n = elm.getNodeName(); - if(n.equals("value")) { - OptionValue value = new OptionValue(opt); - value.setValue(elm.getAttribute("str")); - value.setTargetData(TargetData.parse(elm)); - opt.values.add(value); - } else if(n.equals("default")) { - String defValue = elm.getAttribute("value"); + if (n.equals("value")) { + opt.values.add(new OptionValue(opt, + elm.getAttribute("str"), + TargetData.parse(elm) + )); + } else if (n.equals("default")) { + var def = new OptionDefault(opt); + def.setValueName(elm.getAttribute("value")); String defPlatform = elm.getAttribute(("platform")); - OptionDefault def = new OptionDefault(opt); - def.setValueName(defValue); - if(!defPlatform.isEmpty()) { + if (!defPlatform.isBlank()) { def.setPlatform(defPlatform); } opt.defaults.add(def); } } } - + return opt; } @@ -55,45 +57,32 @@ public void setArgument(String arg) { this.arg = arg; } - + public String getVarName() { - return "OPT_" + arg.toUpperCase(); + return shId("OPT_" + arg.toUpperCase()); } - + public String getArgValue() { - return "${ARG:"+(3+arg.length())+"}"; + return "${ARG:" + (3 + arg.length()) + "}"; } - + public List<OptionValue> getValues() { return values; } - + public List<OptionDefault> getDefaults() { return defaults; } - + public String getValueFunc(String value) { - return "checkopt_"+arg+"_"+value; + return shId("checkopt_" + arg + "_" + value); } - + public String getValuesString() { - if(values.isEmpty()) { - return "()"; - } else if(values.size() == 1) { + if (values.size() == 1) { return values.get(0).getValue(); } else { - StringBuilder vs = new StringBuilder(); - vs.append('('); - for(int i=0;i<values.size();i++) { - if(i < values.size()-1) { - vs.append(values.get(i).getValue()); - vs.append('|'); - } else { - vs.append(values.get(i).getValue()); - } - } - vs.append(')'); - return vs.toString(); + return "(" + values.stream().map(OptionValue::getValue).collect(Collectors.joining("|")) + ")"; } } }
--- a/src/main/java/de/unixwork/uwproj/OptionDefault.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/OptionDefault.java Sun Sep 10 12:52:10 2023 +0200 @@ -2,7 +2,7 @@ public class OptionDefault { private final Option option; - private String value; + private String valueName; private String platform; public OptionDefault(Option opt) { @@ -10,11 +10,11 @@ } public String getValueName() { - return value; + return valueName; } - public void setValueName(String value) { - this.value = value; + public void setValueName(String valueName) { + this.valueName = valueName; } public String getPlatform() { @@ -26,12 +26,12 @@ } public String getFunc() { - return option.getValueFunc(value); + return option.getValueFunc(valueName); } public OptionValue getValue() { for (OptionValue val : option.getValues()) { - if (val.getValue().equals(value)) { + if (val.getValue().equals(valueName)) { return val; } }
--- a/src/main/java/de/unixwork/uwproj/OptionValue.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/OptionValue.java Sun Sep 10 12:52:10 2023 +0200 @@ -2,24 +2,25 @@ import java.util.List; +import static de.unixwork.uwproj.Util.isNotNullOrBlank; + public class OptionValue { - Option option; - - String value; - - TargetData targetData = new TargetData(); - - public OptionValue(Option opt) { - option = opt; + private final Option option; + + private final String value; + + private final TargetData targetData; + + public OptionValue(Option option, String value, TargetData targetData) { + this.option = option; + this.value = value; + this.targetData = targetData; } public String getValue() { return value; } - public void setValue(String value) { - this.value = value; - } public List<String> getDependencies() { return targetData.getDependencies(); @@ -28,20 +29,16 @@ public List<Define> getDefines() { return targetData.getDefines(); } - - public void setTargetData(TargetData data) { - targetData = data; - } - + public String getFunc() { return option.getValueFunc(value); } - + public String getMake() { return targetData.getMake(); } - + public boolean hasMake() { - return !targetData.getMake().trim().isEmpty(); + return isNotNullOrBlank(targetData.getMake()); } }
--- a/src/main/java/de/unixwork/uwproj/PkgConfigPackage.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/PkgConfigPackage.java Sun Sep 10 12:52:10 2023 +0200 @@ -8,16 +8,16 @@ private String maxVersion; public static PkgConfigPackage parse(Element e) throws Exception { - PkgConfigPackage p = new PkgConfigPackage(); + var p = new PkgConfigPackage(); String name = Util.getContent(e); - if(name != null) { + if (name.isBlank()) { + throw new Exception("pkgconfig element: value required"); + } else { p.setName(name); - } else { - throw new Exception("pkgconfig element: value required"); } return p; } - + public String getName() { return name; } @@ -41,7 +41,7 @@ public void setMaxVersion(String maxVersion) { this.maxVersion = maxVersion; } - + public String getPkgConfigParam() { return name; }
--- a/src/main/java/de/unixwork/uwproj/Project.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Project.java Sun Sep 10 12:52:10 2023 +0200 @@ -6,11 +6,12 @@ import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; public class Project { - private final Properties properties = new Properties(); - private final HashMap<String, List<Dependency>> namedDependencies = new HashMap<>(); private final List<Dependency> dependencies = new LinkedList<>(); private final List<Target> targets = new LinkedList<>(); @@ -28,12 +29,10 @@ getDocumentElement(); NodeList dependency_nodes = root.getElementsByTagName("dependency"); NodeList target_nodes = root.getElementsByTagName("target"); - NodeList property_nodes = root.getElementsByTagName("property"); NodeList config_nodes = root.getElementsByTagName("config"); for (int i = 0; i < config_nodes.getLength(); i++) { - Element p = (Element) config_nodes.item(i); - NodeList cfgs = p.getChildNodes(); + NodeList cfgs = config_nodes.item(i).getChildNodes(); for (int c = 0; c < cfgs.getLength(); c++) { Node node = cfgs.item(c); if (node.getNodeType() == Node.ELEMENT_NODE) { @@ -53,16 +52,6 @@ for (int i = 0; i < target_nodes.getLength(); i++) { targets.add(Target.parse(this, (Element) target_nodes.item(i))); } - for (int i = 0; i < property_nodes.getLength(); i++) { - var p = (Element) property_nodes.item(i); - String name = p.getAttribute("name"); - String value = p.getAttribute("value"); - if (!name.isBlank() && !value.isBlank()) { - properties.setProperty(name, value); - } else { - throw new Exception("Missing property name or value"); - } - } if (targets.isEmpty()) { createDefaultTarget();
--- a/src/main/java/de/unixwork/uwproj/Target.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Target.java Sun Sep 10 12:52:10 2023 +0200 @@ -4,69 +4,67 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import static de.unixwork.uwproj.Util.isNotNullOrBlank; +import static de.unixwork.uwproj.Util.isNullOrBlank; + public class Target { private String name; private String prefix; - + private final List<String> dependencies = new LinkedList<>(); private final List<String> optionalDependencies = new LinkedList<>(); private final List<Define> defines = new LinkedList<>(); private final List<Feature> features = new LinkedList<>(); private final List<Option> options = new LinkedList<>(); - + private boolean allDependencies = false; - + public static Target parse(Project project, Element element) throws Exception { - Target target = new Target(); - + var target = new Target(); + String name = element.getAttribute("name"); - if(!name.isEmpty()) { + if (!name.isBlank()) { target.setName(name); } - + NodeList nodes = element.getChildNodes(); - for(int i=0;i<nodes.getLength();i++) { + for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { - Element elm = (Element)node; + Element elm = (Element) node; String n = elm.getNodeName(); - if(n.equals("feature")) { - Feature feature = Feature.parse(project, elm); - target.addFeature(feature); - } else if(n.equals("define")) { - String def = elm.getAttribute("name"); - String defval = elm.getAttribute("value"); - if (def.isBlank()) { - throw new Exception("define element requires name attribute"); - } - target.addDefine(def, defval); - } else if(n.equals("dependencies")) { - String deps = Util.getContent(elm); - String[] dependencies = deps.split(","); - for(String dependency : dependencies) { - dependency = dependency.trim(); - target.addDependency(dependency, false); - } - } else if(n.equals("alldependencies")) { + if (n.equals("feature")) { + target.addFeature(Feature.parse(project, elm)); + } else if (n.equals("define")) { + target.addDefine( + elm.getAttribute("name"), + elm.getAttribute("value") + ); + } else if (n.equals("dependencies")) { + Arrays.stream(Util.getContent(elm).split(",")) + .map(String::trim) + .forEach(target::addDependency); + } else if (n.equals("alldependencies")) { target.setAllDependencies(true); - } else if(n.equals("option")) { - Option opt = Option.parse(project, elm); + } else if (n.equals("option")) { + var opt = Option.parse(elm); target.addOption(opt); project.addOption(opt); } } } - - if (target.prefix == null && target.name != null) { + + if (isNullOrBlank(target.prefix) && isNotNullOrBlank(target.name)) { target.setPrefix(name.toUpperCase()); } - + return target; } - + public String getName() { return name; } @@ -82,17 +80,21 @@ public void setPrefix(String prefix) { this.prefix = prefix; } - + + private String withPrefix(String id) { + return prefix == null ? id : String.format("%s_%s", prefix, id); + } + public String getCFlags() { - return prefix == null ? "CFLAGS" : prefix + "_CFLAGS"; + return withPrefix("CFLAGS"); } - + public String getLDFlags() { - return prefix == null ? "LDFLAGS" : prefix + "_LDFLAGS"; + return withPrefix("LDFLAGS"); } - + public String getCXXFlags() { - return prefix == null ? "CXXFLAGS" : prefix + "_CXXFLAGS"; + return withPrefix("CXXFLAGS"); } public List<String> getDependencies() { @@ -100,13 +102,17 @@ } public void addDependency(String dependency, boolean optional) { - if(optional) { + if (optional) { optionalDependencies.add(dependency); } else { dependencies.add(dependency); } } + public void addDependency(String dependency) { + dependencies.add(dependency); + } + public List<String> getOptionalDependencies() { return optionalDependencies; } @@ -118,30 +124,30 @@ public void setAllDependencies(boolean allDependencies) { this.allDependencies = allDependencies; } - + public void addDefine(String name, String value) { - Define def = new Define(); - def.setName(name); - def.setValue(value); - defines.add(def); + if (name.isBlank()) { + throw new IllegalArgumentException("define element requires name attribute"); + } + defines.add(new Define(name, value)); } - + public List<Define> getDefines() { return defines; } - + public void addFeature(Feature f) { features.add(f); } - + public List<Feature> getFeatures() { return features; } - + public void addOption(Option o) { options.add(o); } - + public List<Option> getOptions() { return options; }
--- a/src/main/java/de/unixwork/uwproj/TargetData.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/TargetData.java Sun Sep 10 12:52:10 2023 +0200 @@ -4,6 +4,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -12,39 +13,33 @@ private final List<String> dependencies = new LinkedList<>(); private final StringBuilder make = new StringBuilder(); - public static TargetData parse(Element element) throws Exception { - TargetData data = new TargetData(); - + public static TargetData parse(Element element) { + var target = new TargetData(); + NodeList nodes = element.getChildNodes(); - for(int i=0;i<nodes.getLength();i++) { + for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { - Element elm = (Element)node; + Element elm = (Element) node; String n = elm.getNodeName(); - if(n.equals("define")) { - String def = elm.getAttribute("name"); - String defval = elm.getAttribute("value"); - if (def.isBlank()) { - throw new Exception("define element requires name attribute"); - } - data.addDefine(new Define(def, defval)); - } else if(n.equals("dependencies")) { - String deps = Util.getContent(elm); - String[] dependencies = deps.split(","); - for(String dependency : dependencies) { - dependency = dependency.trim(); - data.addDependency(dependency); - } - } else if(n.equals("make")) { - String m = Util.getContent(elm); - data.addMake(m); + if (n.equals("define")) { + target.addDefine( + elm.getAttribute("name"), + elm.getAttribute("value") + ); + } else if (n.equals("dependencies")) { + Arrays.stream(Util.getContent(elm).split(",")) + .map(String::trim) + .forEach(target::addDependency); + } else if (n.equals("make")) { + target.addMake(Util.getContent(elm)); } } } - - return data; + + return target; } - + public List<Define> getDefines() { return defines; } @@ -56,15 +51,18 @@ public String getMake() { return make.toString(); } - - public void addDefine(Define d) { - defines.add(d); + + public void addDefine(String name, String value) { + if (name.isBlank()) { + throw new IllegalArgumentException("define element requires name attribute"); + } + defines.add(new Define(name, value)); } - + public void addDependency(String d) { dependencies.add(d); } - + public void addMake(String m) { make.append(m.trim()); make.append('\n');
--- a/src/main/java/de/unixwork/uwproj/Util.java Wed Sep 06 22:55:42 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Util.java Sun Sep 10 12:52:10 2023 +0200 @@ -16,7 +16,8 @@ for (int i = 0; i < nodes.getLength(); i++) { var node = nodes.item(i); if (node.getNodeType() == Node.TEXT_NODE) { - return node.getTextContent(); + final var v = node.getNodeValue(); + return v == null ? "" : v; } } return ""; @@ -29,4 +30,18 @@ public static boolean isNotNullOrBlank(String s) { return s != null && !s.isBlank(); } + + /** + * Creates an identifier from the given string that can be used as an identifier in a POSIX shell script. + * <p> + * If the given string does not contain any character that is illegal in a POSIX shell variable or function name, + * the string is returned unmodified. + * + * @param s the input string + * @return the sanitized string + */ + public static String shId(String s) { + // TODO: implement + return s; + } }
--- a/test/make/configure.vm Wed Sep 06 22:55:42 2023 +0200 +++ b/test/make/configure.vm Sun Sep 10 12:52:10 2023 +0200 @@ -412,7 +412,7 @@ fi #end #foreach( $pkg in $dependency.pkgconfig ) - printf "checking for pkg-config package $pkg.getPkgConfigParam()... " + printf "checking for pkg-config package $pkg.name... " $PKG_CONFIG $pkg.getPkgConfigParam() if [ $? -ne 0 ]; then echo no
--- a/uwproj.xsd Wed Sep 06 22:55:42 2023 +0200 +++ b/uwproj.xsd Sun Sep 10 12:52:10 2023 +0200 @@ -2,23 +2,19 @@ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://unixwork.de/uwproj" targetNamespace="http://unixwork.de/uwproj" - elementFormDefault="qualified"> + elementFormDefault="qualified" + version="0.1" +> <xs:element name="project" type="ProjectType"/> <xs:complexType name="ProjectType"> <xs:sequence> - <xs:element name="property" type="PropertyType" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="config" type="ConfigType" minOccurs="0"/> <xs:element name="dependency" type="DependencyType" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="target" type="TargetType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> - <xs:complexType name="PropertyType"> - <xs:attribute name="name" type="xs:string" use="required"/> - <xs:attribute name="value" type="xs:string" use="required"/> - </xs:complexType> - <xs:complexType name="ConfigType"> <xs:sequence> <xs:element name="var" type="ConfigVarType" minOccurs="0" maxOccurs="unbounded"/>