Sysdeftools additional support for merging misordered system definitions. More extensive validation. Minor bug fixes. Bash wrappers for perl scripts for unix installs.
authorBob Rosenberg <bob.rosenberg@nokia.com>
Mon, 18 Oct 2010 10:33:54 +0100
changeset 660 66ff3e731c60
parent 659 7afa5fba0903
child 661 199bb033aacf
Sysdeftools additional support for merging misordered system definitions. More extensive validation. Minor bug fixes. Bash wrappers for perl scripts for unix installs.
metatools/sysdeftools/group/bld.inf
metatools/sysdeftools/group/contents.xml
metatools/sysdeftools/group/unixperlcmd
metatools/sysdeftools/joinsysdef.pl
metatools/sysdeftools/lib/joinsysdef-module.xsl
metatools/sysdeftools/lib/mergesysdef-module.xsl
metatools/sysdeftools/lib/test-model.xsl
metatools/sysdeftools/rootsysdef.pl
--- a/metatools/sysdeftools/group/bld.inf	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/group/bld.inf	Mon Oct 18 10:33:54 2010 +0100
@@ -63,6 +63,10 @@
 ../joinsysdef.bat		/epoc32/tools/sysdeftools/joinsysdef.bat
 ../rootsysdef.bat		/epoc32/tools/sysdeftools/rootsysdef.bat
 
+unixperlcmd		/epoc32/tools/sysdeftools/checklinks
+unixperlcmd		/epoc32/tools/sysdeftools/joinsysdef
+unixperlcmd		/epoc32/tools/sysdeftools/rootsysdef
+
 // Xalan-calling .bat/unix files (identical, can export from single file)
 ../joinandparesysdef.bat		/epoc32/tools/sysdeftools/joinandparesysdef.bat
 ../filtering.bat		/epoc32/tools/sysdeftools/filtering.bat
--- a/metatools/sysdeftools/group/contents.xml	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/group/contents.xml	Mon Oct 18 10:33:54 2010 +0100
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ProductsDefinition schema="3.0.0">
 	<product name="BuildEnvironment" long-name="Build Environment">
-		<tool name="sysdeftools" long-name="System Definition Tools" default-src="metatools/sysdeftools" default-dst="/" version="1.0.2">
+		<tool name="sysdeftools" long-name="System Definition Tools" default-src="metatools/sysdeftools" default-dst="/" version="1.0.3">
 
 			<!-- core functionality -->
 			<file filename="*.pl"/> 
@@ -29,6 +29,10 @@
 			</windows>
 		
 			<linux>
+			  <file filename="unixperlcmd" src="metatools/sysdeftools/group/" dstFile="/checklinks"/> 
+			  <file filename="unixperlcmd" src="metatools/sysdeftools/group/" dstFile="/joinsysdef"/> 
+			  <file filename="unixperlcmd" src="metatools/sysdeftools/group/" dstFile="/rootsysdef"/> 
+
 				<!-- Xalan-calling unix files -->
 			  <file filename="unixxslcmd" src="metatools/sysdeftools/group/" dstFile="/joinandparesysdef"/> 
 			  <file filename="unixxslcmd" src="metatools/sysdeftools/group/" dstFile="/filtering"/> 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/metatools/sysdeftools/group/unixperlcmd	Mon Oct 18 10:33:54 2010 +0100
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Description:
+#  Perl wrapper for Unix
+
+BASEDIR=`dirname $0`
+exec perl $BASEDIR/$0.pl $@
--- a/metatools/sysdeftools/joinsysdef.pl	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/joinsysdef.pl	Mon Oct 18 10:33:54 2010 +0100
@@ -276,17 +276,19 @@
 		}
 	elsif($tag eq 'unit')
 		{
-		foreach my $atr ('bldFile','mrp','base','proFile')
+		foreach my $atr ('bldFile','mrp','base')
 			{
 			my $link= $node->getAttribute($atr);
 			if($link && !($link=~/^\//))
 				{
 				$link= &abspath(File::Basename::dirname($file)."/$link");
-				foreach my $a (keys %rootmap) {
+				foreach my $a (sort {length($b) - length($a)} keys(%rootmap)) {
 					$link=~s,^$a,$rootmap{$a},ie;
 				}
 				# remove leading ./  which is used to indicate that paths should remain relative
 				$link=~s,^\./([^/]),$1,; 
+				# remove windows drive letter -- only allow paths on the same drive. Use root attribuite to build across drives / filesystems
+				$link=~s,^[a-z]:/,/,i;	
 				$node->setAttribute($atr,$link);
 				}
 			}
--- a/metatools/sysdeftools/lib/joinsysdef-module.xsl	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/lib/joinsysdef-module.xsl	Mon Oct 18 10:33:54 2010 +0100
@@ -136,7 +136,8 @@
 	<xsl:variable name="linked" select="document(@href,.)/*"/>
 	<xsl:for-each select="$linked">
 		<xsl:apply-templates select="//*[(self::component or self::collection or self::package or self::layer) and @href]" mode="scan-for-namespaces"/>
-		<xsl:for-each select="//namespace::* | @id-namespace">
+		<xsl:for-each select="//namespace::*[.!='http://www.w3.org/XML/1998/namespace'] | @id-namespace">
+			<!-- ignore XML namespace -->
 			<xsl:value-of select="concat(name(),' ',.,'&#xa;')"/>
 		</xsl:for-each>
 	</xsl:for-each>
--- a/metatools/sysdeftools/lib/mergesysdef-module.xsl	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/lib/mergesysdef-module.xsl	Mon Oct 18 10:33:54 2010 +0100
@@ -136,7 +136,7 @@
 	<xsl:if test="name(*) != name($other/*)">
 		<xsl:message terminate="yes">ERROR: Can only merge system models of the same rank</xsl:message>
 	</xsl:if>
-	 
+
 	<xsl:copy>
 		<xsl:attribute name="schema">
 			<xsl:call-template name="compare-versions">
@@ -220,9 +220,45 @@
 			<xsl:with-param name="replaces" select="$replaces"/>
 		</xsl:apply-templates>		
 
+		<!-- and now check for error cases, and tack those on -->
+		<xsl:call-template name="check-and-add-out-of-order-items">
+			<xsl:with-param name="match" select="$other/systemModel"/>
+			<xsl:with-param name="down" select="$down"/>
+			<xsl:with-param name="replaces" select="$replaces"/>
+		</xsl:call-template> 
 	</xsl:copy>
 </xsl:template>
 
+<xsl:template name="check-and-add-out-of-order-items"><xsl:param name="match"/><xsl:param name="down"/><xsl:param name="replaces"/>
+	<xsl:if test="$match">
+		<!-- determine the order of the children in the upstream and downstream docs --> 
+		<xsl:variable name="up-order">
+			<xsl:for-each select="*[@id=$match/*[not(@before)]/@id]"><xsl:value-of select="@id"/><xsl:text> </xsl:text></xsl:for-each>
+		</xsl:variable>
+		<xsl:variable name="down-order">
+			<xsl:for-each select="$match/*[@id = current()/*[not(@before)]/@id]"><xsl:value-of select="@id"/> <xsl:text> </xsl:text></xsl:for-each>
+		</xsl:variable>
+
+		<!-- check for error cases, and tack those on -->
+		<xsl:if test="$up-order != $down-order">
+			<xsl:variable name="down-final" select="$match/*[@id = current()/*[not(@before)]/@id][last()]/@id"/>
+				<!-- the last item in the downstream model that is also in the upstream one -->
+
+			<xsl:variable name="out-of-order" select="$match/*[@id][not(@before=current()/*/@id) and not(@id=current()/*/@id) and following-sibling::*[@id=$down-final]]"/>
+				<!-- contains all items in the downstream model that can't be put in order-->
+			<xsl:if test="$out-of-order">
+				<xsl:message>Warning: Order of <xsl:value-of select="name(*)"/>s in upstream document does not match order in downstream.  The following <xsl:value-of select="name(*)"/>s will be appended to the end<xsl:if test="@id"> of <xsl:value-of select="@id"/></xsl:if>: <xsl:for-each select="$out-of-order"><xsl:value-of select="concat(@id,' ')"/></xsl:for-each></xsl:message>
+			</xsl:if>
+			<xsl:apply-templates mode="merge-copy-of" select="$out-of-order">
+				<xsl:with-param name="origin" select="$down"/>
+				<xsl:with-param name="root" select="current()/ancestor::SystemDefinition"/>			
+				<xsl:with-param name="replaces" select="$replaces"/>
+			</xsl:apply-templates>			
+		</xsl:if>
+	</xsl:if>
+</xsl:template>
+
+
 <xsl:template match="@*|*|comment()" mode="merge-models"><xsl:copy-of select="."/></xsl:template>
 
 
@@ -370,17 +406,37 @@
 	</xsl:call-template>
 </xsl:variable>
 
+
+	<!-- check the order of the items in the upstream and downstream doc. If they don't match up, we can't merge them nicely -->
+	<xsl:variable name="up-order">
+		<xsl:for-each select="../*[@id=$match/../*[not(@before)]/@id]"><xsl:value-of select="@id"/><xsl:text> </xsl:text></xsl:for-each>
+	</xsl:variable>
+	<xsl:variable name="down-order">
+		<xsl:for-each select="$match/../*[@id = current()/../*[not(@before)]/@id]"><xsl:value-of select="@id"/> <xsl:text> </xsl:text></xsl:for-each>
+	</xsl:variable>
+
 	<!-- prev = the previous item before the current one (no metas, only named items)-->
 	<xsl:variable name="prev" select="preceding-sibling::*[@id=$prev-id]"/> 
 
 
 	<!-- copy all items between this and prev that are solely in the downstream model -->	 		
 
+	<!-- <xsl:variable name="upstream-ids" select="ancestor::SystemDefinition//@id[parent::component or parent::collection or parent::package or parent::layer]"/> -->
+	<xsl:variable name="upstream-ids" select="../*/@id"/> <!-- this is much faster than using all IDs. before only currently works in the same parent anyway -->
+
+	<!-- $upstream-ids is used to avoid inserting an item that's being moved -->
+
 	<xsl:choose>
+		<xsl:when test="$match and $up-order != $down-order">
+		<!-- if the contents are in a different order, there's no way to merge them together. Don't try. Tack them on to the end later -->
+				<xsl:message>Warning: Order of <xsl:value-of select="name()"/>s in upstream <xsl:value-of select="../@id"/>
+				<xsl:if test="not(../@id)">document</xsl:if> does not match the order of the <xsl:value-of select="name()"/>s in common in the downstream equivalent. Contents will not be properly merged: <xsl:value-of select="$up-order"/>  != 	<xsl:value-of select="$down-order"/></xsl:message>
+		</xsl:when>
+
 		<xsl:when test="$match and $prev">
 			<xsl:call-template name="copy-sorted-content">
 				<xsl:with-param name="base" select="../*[@id]"/>
-				<xsl:with-param name="to-sort" select="$other/*[@id][following-sibling::*[@id=$match/@id]][preceding-sibling::*[@id=$prev/@id]]"/>
+				<xsl:with-param name="to-sort" select="$other/*[@id and not(@before=$upstream-ids)][following-sibling::*[@id=$match/@id]][preceding-sibling::*[@id=$prev/@id]]"/>
 				<xsl:with-param name="start" select="$prev"/>
 				<xsl:with-param name="end" select="."/>
 				<xsl:with-param name="down" select="$down"/>
@@ -389,7 +445,7 @@
 		<xsl:when test="$match and not($prev)">
 			<xsl:call-template name="copy-sorted-content">
 				<xsl:with-param name="base" select="../*[@id]"/>
-				<xsl:with-param name="to-sort" select="$other/*[@id][following-sibling::*[@id=$match/@id]]"/>
+				<xsl:with-param name="to-sort" select="$other/*[@id and not(@before=$upstream-ids)][following-sibling::*[@id=$match/@id]]"/>
 				<xsl:with-param name="start" select="$prev"/>
 				<xsl:with-param name="end" select="."/>
 				<xsl:with-param name="down" select="$down"/>
@@ -398,6 +454,7 @@
 	</xsl:choose>
 
  	<!-- just copy anything identified as being before this, assume they're all ok -->
+
 	<xsl:apply-templates mode="merge-copy-of" select="$other/*[@before=current()/@id]">
 		<xsl:with-param name="remove-before" select="1"/>
 		<xsl:with-param name="origin" select="$down"/>
@@ -409,11 +466,11 @@
 		<xsl:apply-templates select="@*" mode="merge-models"> <!-- copy upstream attributes -->
 			<xsl:with-param name="other" select="$match"/>
 		</xsl:apply-templates>
-		
-		<xsl:if test="self::component and not(@origin-model) and $up/@name">
+		<xsl:if test="self::component and not(@origin-model) and ($up/@name or ancestor::systemModel/@name)">
 			<!-- insert origin-model and optional root for components only -->
 			<xsl:attribute name="origin-model">
 				<xsl:value-of select="$up/@name"/>
+				<xsl:if test="not($up/@name)"><xsl:value-of select="ancestor::systemModel/@name"/></xsl:if>
 			</xsl:attribute>
 			<xsl:if test="not(@root)">
 				<xsl:copy-of select="$up/@root"/>
@@ -466,9 +523,16 @@
 				</xsl:for-each>
 			</xsl:otherwise>
 		</xsl:choose>
-	</xsl:copy>
 
-		</xsl:otherwise>
+		<!-- and now check for error cases, and tack those on -->
+		<xsl:call-template name="check-and-add-out-of-order-items">
+			<xsl:with-param name="match" select="$match"/>
+			<xsl:with-param name="down" select="$down"/>
+			<xsl:with-param name="replaces" select="$replaces"/>
+		</xsl:call-template> 
+
+	</xsl:copy>
+ 	</xsl:otherwise>
 	</xsl:choose>
 </xsl:template>
 
@@ -554,9 +618,10 @@
 					<xsl:with-param name="remove-before" select="$remove-before"/>
 					<xsl:with-param name="root" select="$root"/>
 				</xsl:call-template>
-				<xsl:if test="not(@origin-model) and $origin/@name">
+				<xsl:if test="not(@origin-model) and ($origin/@name or ancestor::systemModel/@name)">
 					<xsl:attribute name="origin-model">
 						<xsl:value-of select="$origin/@name"/>
+						<xsl:if test="not($origin/@name)"><xsl:value-of select="ancestor::systemModel/@name"/></xsl:if>
 					</xsl:attribute>
 					<xsl:if test="not(@root)">
 						<xsl:copy-of select="$origin/@root"/>
--- a/metatools/sysdeftools/lib/test-model.xsl	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/lib/test-model.xsl	Mon Oct 18 10:33:54 2010 +0100
@@ -1,4 +1,7 @@
-<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <!DOCTYPE XSLT  [
+      <!ENTITY AZ  "ABCDEFGHIJKLMNOPQRSTUVWXYZ">
+      <!ENTITY az  "abcdefghijklmnopqrstuvwxyz">
+ ]><xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 	All rights reserved.
 	This component and the accompanying materials are made available
@@ -62,7 +65,7 @@
 	<xsl:param name="filename" select="$Filename"/>
 <xsl:call-template name="Section">
 	<xsl:with-param name="text">System Definition: <xsl:value-of select="*/@name"/></xsl:with-param>
-	<xsl:with-param name="sub"><xsl:value-of select="(string-length($all-ids) - string-length(translate($all-ids,' ',''))) div 2 "/> items</xsl:with-param>
+	<xsl:with-param name="sub"><xsl:value-of select="(string-length($all-ids) - string-length(translate($all-ids,' ','')) - 1) div 2 "/> items</xsl:with-param>
 </xsl:call-template>
 	<xsl:apply-templates select="*">
 		<xsl:with-param name="filename" select="$filename"/>
@@ -72,9 +75,10 @@
 <xsl:template match="/SystemDefinition[starts-with(@schema,'3.0.')] | systemModel">
 	<xsl:param name="filename"  select="$Filename"/>
 		
-<xsl:if test="//unit">
+<xsl:if test="//unit and not(self::systemModel)">
 <xsl:call-template name="Section">
 	<xsl:with-param name="text"><xsl:value-of select="translate(substring(name(*),1,1),'clp','CLP')"/><xsl:value-of select="substring(name(*),2)"/> Definition: <xsl:value-of select="*/@name"/></xsl:with-param>
+	<xsl:with-param name="id"><xsl:value-of select="*/@id"/></xsl:with-param>
 	<xsl:with-param name="sub"><xsl:value-of select="count(//unit)"/> unit<xsl:if test="count(//unit)!=1">s</xsl:if></xsl:with-param>
 </xsl:call-template>
 </xsl:if>
@@ -84,6 +88,11 @@
 	<xsl:apply-templates select="*">
 		<xsl:with-param name="filename" select="$filename"/>
 	</xsl:apply-templates>
+	<xsl:for-each select="//text()[normalize-space(.)!='']">
+		<xsl:if test="not(ancestor::meta)">
+			<xsl:call-template name="Error"><xsl:with-param name="text">Text content not valid in <xsl:value-of select="name(..)"/> (<xsl:value-of select="normalize-space(.)"/>)</xsl:with-param></xsl:call-template>
+		</xsl:if>
+	</xsl:for-each>
 </xsl:template>
 
 
@@ -91,11 +100,81 @@
 	<xsl:call-template name="Error"><xsl:with-param name="text">Attribute <xsl:value-of select="name()"/>="<xsl:value-of select="."/>" is not valid for <xsl:value-of select="name(..)"/></xsl:with-param></xsl:call-template>
 </xsl:template>
 
-<xsl:template match="@before|@id|package/@span|layer/@span|collection/@level|package/@level|package/@levels|layer/@levels" mode="valid"/> <!-- really should check syntax -->
+<xsl:template match="@before|package/@span|layer/@span|collection/@level|package/@level|package/@levels|layer/@levels" mode="valid"/> <!-- really should check syntax -->
+
+<xsl:template match="@href|@id|@filter|package/@version|unit/@version|unit/@prebuilt" mode="valid"/> 
+
+<xsl:template match="component/@introduced" mode="valid"/>
+<xsl:template match="component/@deprecated" mode="valid">
+	<xsl:if test="../@purpose='mandatory'">
+		<xsl:call-template name="Warning"><xsl:with-param name="text">Deprecated component <id><xsl:value-of select="../@id"/></id> should not be mandatory</xsl:with-param></xsl:call-template>
+	</xsl:if>
+</xsl:template>
+
+<xsl:template match="@name" mode="valid"> <!-- look for various naming troubles -->
+	<xsl:variable name="pre"><xsl:value-of select="name(..)"/> with name "<xsl:value-of select="."/>"</xsl:variable>
+	<xsl:if test="normalize-space(.)!=.">
+		<xsl:call-template name="Warning"><xsl:with-param name="text"><xsl:value-of select="$pre"/> has unexpected whitespace</xsl:with-param></xsl:call-template>
+	</xsl:if>
+
+	<xsl:choose> <!-- these are likely to all be the same error -->
+		<xsl:when test=".=../@id or .=substring-after(../@id,':')">
+			<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="$pre"/> is the same as the id</xsl:with-param></xsl:call-template>
+		</xsl:when>
+
+		<xsl:when test="contains(.,'_')">
+			<xsl:call-template name="Error"><xsl:with-param name="text">
+			<xsl:value-of select="$pre"/> must not contain the underscore character (_)</xsl:with-param></xsl:call-template>
+		</xsl:when>
+		<xsl:when test="translate(.,'&az;0123456789_ ','')=''">
+			<xsl:call-template name="Warning"><xsl:with-param name="text">The human-readable name for <xsl:value-of select="name(..)"/> "<xsl:value-of select="."/>" cannot be entirely lowercase</xsl:with-param></xsl:call-template>
+		</xsl:when>
+	</xsl:choose>
+
+	<xsl:variable name="spaced" select="concat(' ',.,' ')"/>
+	<xsl:variable name="this" select="."/>
+	<xsl:variable name="terms" select="document('')/*/xsl:template[@name='bad-names']/*"/>
+	<xsl:variable name="std" select="document('')/*/xsl:template[@name='std-names']/*"/>
 
-<xsl:template match="@name|@href|@filter|package/@version|unit/@version|unit/@prebuilt" mode="valid"/> 
+	<xsl:for-each select="$terms"> <!-- common errors in names -->
+		<xsl:if test="contains($spaced,concat(' ',.,' '))">
+			<xsl:choose>
+				<xsl:when test="name()='bad'">
+					<xsl:call-template name="Warning"><xsl:with-param name="text">
+						<xsl:value-of select="$pre"/> should use "<xsl:value-of select="@ok"/>"</xsl:with-param></xsl:call-template>
+				</xsl:when>
+				<xsl:when test="name()='pref'">
+					<xsl:call-template name="Note"><xsl:with-param name="text">
+						<xsl:value-of select="$pre"/> should use "<xsl:value-of select="@ok"/>" instead of "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+				</xsl:when>
+			</xsl:choose>
+		</xsl:if>
+	</xsl:for-each>
 
-<xsl:template match="component/@introduced|component/@deprecated" mode="valid"/> 
+	<xsl:if test="../self::component and 
+		( (substring(.,string-length(.) - string-length(' Plugin') + 1) = ' Plugin') or
+		 (substring(.,string-length(.) - string-length(' Plugins') + 1) = ' Plugins') ) 
+		  and not(contains(../@class,'plugin'))">
+		<xsl:call-template name="Note"><xsl:with-param name="text">
+			<xsl:value-of select="$pre"/> should have class "plugin"</xsl:with-param></xsl:call-template>
+	</xsl:if>
+
+	<xsl:for-each select="$std"> <!-- standard naming schemes -->
+		<xsl:choose>
+			<xsl:when test="name()='suffix' and substring($this/../@id,string-length($this/../@id) - string-length(.) + 1)=. 
+				and not(substring($this,string-length($this) - string-length(@name) + 1) = @name or  substring($this,string-length($this) - string-length(@or) + 1) = @or)">
+				<xsl:call-template name="Note"><xsl:with-param name="text">
+					<xsl:value-of select="$pre"/> should end with "...<xsl:value-of select="@name"/>"<xsl:if test="@or"> or "...<xsl:value-of select="@or"/>"</xsl:if></xsl:with-param></xsl:call-template>
+			</xsl:when>
+			<xsl:when test="name()='prefix' and starts-with($this/../@id,.) and not(starts-with($this,@name))">
+				<xsl:call-template name="Note"><xsl:with-param name="text">
+					<xsl:value-of select="$pre"/> should start with "<xsl:value-of select="@name"/>..."</xsl:with-param></xsl:call-template>
+			</xsl:when>
+		</xsl:choose>
+	</xsl:for-each>
+
+</xsl:template>
+
 
 <xsl:template match="component/@origin-model" mode="valid"/>
 
@@ -111,8 +190,17 @@
 <xsl:template match="@*[namespace-uri()='http://www.nokia.com/qt' and local-name()='proFile']" mode="valid"/> 
 	
 
+<xsl:template match="@*[namespace-uri()='http://www.nokia.com/qt' and local-name()='qmakeArgs' and not(../@*[local-name()='proFile'])]" mode="valid"> 
+	<xsl:call-template name="Error"><xsl:with-param name="text">Extension attribute <code><xsl:value-of select="local-name()"/>="<xsl:value-of select="."/>"</code> in namespace <xsl:value-of select="namespace-uri()"/> cannot be used without a proFile extention attribute</xsl:with-param></xsl:call-template>
+</xsl:template>
+
+
 <xsl:template match="@*[namespace-uri()='http://www.nokia.com/qt' and local-name()='qmakeArgs']" mode="valid"> 
-	<xsl:call-template name="Note"><xsl:with-param name="text">Should avoid using extension attribute <xsl:value-of select="local-name()"/>="<xsl:value-of select="."/>" in namespace <xsl:value-of select="namespace-uri()"/></xsl:with-param></xsl:call-template>
+	<xsl:call-template name="Note"><xsl:with-param name="text">Use of extension attribute <code><xsl:value-of select="local-name()"/>="<xsl:value-of select="."/>"</code> in namespace <xsl:value-of select="namespace-uri()"/> is deprecated. Put contents in the "<code>symbian: { ... }</code>" section of <xsl:value-of select="../@bldFile"/>/<xsl:value-of select="../@*[namespace-uri()='http://www.nokia.com/qt' and local-name()='proFile']"/></xsl:with-param></xsl:call-template>
+</xsl:template>
+
+<xsl:template match="@*[namespace-uri()='http://www.nokia.com/qt' and local-name()='qmakeArgs' and .='-r']" mode="valid"> 
+	<xsl:call-template name="Warning"><xsl:with-param name="text">Extension attribute <code><xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</code> must be removed. The attribute is deprecated and that is the default behaviour</xsl:with-param></xsl:call-template>
 </xsl:template>
 
 
@@ -123,6 +211,21 @@
 </xsl:template>
 
 
+<xsl:template name="bad-names">
+	<bad ok="SHAI">shai</bad>
+	<bad ok="API">api</bad>
+	<pref ok="A-GPS">AGPS</pref>
+	<pref ok="APIs">Headers</pref>
+</xsl:template>
+
+<xsl:template name="std-names">
+	<suffix name=" API">_api</suffix>
+	<suffix name=" SHAI">_shai</suffix>
+	<suffix name=" Info">_info</suffix>
+	<suffix name=" Public Interfaces">_pub</suffix>
+	<suffix name=" Platform Interfaces">_plat</suffix>
+	<suffix name=" Test" or="Tests">test</suffix>
+</xsl:template>
 
 <xsl:template name="validate-class">
 	<ok>plugin</ok>
@@ -219,26 +322,37 @@
 
 
 <xsl:template match="*" priority="-2">
-	<xsl:call-template name="Error"><xsl:with-param name="text">Element "<xsl:value-of select="name()"/>" is not valid in the context of "<xsl:value-of select="name(..)"/>"</xsl:with-param></xsl:call-template>
+	<xsl:call-template name="Error"><xsl:with-param name="text">Element "<xsl:value-of select="name()"/>" is not valid in the context of "<xsl:value-of select="name(..)"/>"<xsl:if test="ancestor::meta"> in <xsl:value-of select="ancestor::meta/@rel"/> metadata section</xsl:if></xsl:with-param></xsl:call-template>
 </xsl:template>
 
-<xsl:template match="component[not(parent::collection)] | collection[not(parent::package)] | package[not(parent::package or parent::layer or (parent::SystemDefinition and count(../*)=1))] | layer[not(parent::systemModel)] " priority="3">
-	<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" has invalid parent <xsl:value-of select="name(..)"/> "<xsl:value-of select="../@id"/>"</xsl:with-param></xsl:call-template>
+<xsl:template match="component[not(parent::collection) or (parent::SystemDefinition and count(../*)=1)] | 
+	collection[not(parent::package) or (parent::SystemDefinition and count(../*)=1)] | 
+	package[not(parent::package or parent::layer or (parent::SystemDefinition and count(../*)=1))] |
+	layer[not(parent::systemModel)] " priority="3">
+	<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<id><xsl:value-of select="@id"/></id>" has invalid parent <xsl:value-of select="name(..)"/> "<id><xsl:value-of select="../@id"/></id>"</xsl:with-param></xsl:call-template>
 </xsl:template>
 
 <xsl:template match="layer | package | collection | component">
 	<xsl:param name="filename"/>
 
+<xsl:if test="self::package and not(parent::SystemDefinition)">
+<xsl:call-template name="Section">
+	<xsl:with-param name="id"><xsl:value-of select="@id"/></xsl:with-param>
+	<xsl:with-param name="text"><xsl:value-of select="translate(substring(name(),1,1),'clp','CLP')"/><xsl:value-of select="substring(name(),2)"/>: <xsl:value-of select="@name"/></xsl:with-param>
+	<xsl:with-param name="sub"><xsl:value-of select="count(descendant::unit)"/> unit<xsl:if test="count(descendant::unit)!=1">s</xsl:if></xsl:with-param>
+</xsl:call-template>
+</xsl:if>
+
 <xsl:apply-templates select="@*" mode="valid"/>
 <xsl:apply-templates select="@id"/>
 <xsl:if test="self::component">
 	<xsl:choose>
 		<xsl:when test="count(unit[not(@filter | @version)]) = 0 "/>
 		<xsl:when test="count(unit[not(@version)]) &gt; 1 and @filter='s60'">
-			<xsl:call-template name="Warning"><xsl:with-param name="text">S60 Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(unit)"/> units.</xsl:with-param></xsl:call-template>
+			<xsl:call-template name="Warning"><xsl:with-param name="text">S60 Component <id><xsl:value-of select="@id"/></id> has <xsl:value-of select="count(unit)"/> units.</xsl:with-param></xsl:call-template>
 		</xsl:when>
 		<xsl:when test="count(unit[not(@version)]) &gt; 1">
-			<xsl:call-template name="Error"><xsl:with-param name="text">Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(unit)"/> units.</xsl:with-param></xsl:call-template>
+			<xsl:call-template name="Error"><xsl:with-param name="text">Component "<id><xsl:value-of select="@id"/></id>" has <xsl:value-of select="count(unit)"/> units.</xsl:with-param></xsl:call-template>
 		</xsl:when>
 	</xsl:choose>
 	<xsl:choose>
@@ -255,22 +369,22 @@
 <xsl:if test="@href">
 	<xsl:variable name="child" select="document(@href,.)/SystemDefinition"/>
 	<xsl:if test="@id!=$child/@id">
-		<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" must match ID in linked file "<xsl:value-of select="@href"/>"</xsl:with-param></xsl:call-template>
+		<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<id><xsl:value-of select="@id"/></id>" must match ID in linked file "<xsl:value-of select="@href"/>"</xsl:with-param></xsl:call-template>
 	</xsl:if>
 	<xsl:if test="$child/@href">
-		<xsl:call-template name="Error"><xsl:with-param name="text">linked <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" cannot be a link</xsl:with-param></xsl:call-template>
+		<xsl:call-template name="Error"><xsl:with-param name="text">linked <xsl:value-of select="name()"/> "<id><xsl:value-of select="@id"/></id>" cannot be a link</xsl:with-param></xsl:call-template>
 	</xsl:if>
 	<xsl:for-each select="@*[name()!='id']">
 		<xsl:if test="$child/@*[name()=name(current())]">
-			<xsl:call-template name="Warning"><xsl:with-param name="text">linked <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" has duplicate attribute to linking document. Duplicate ignored.</xsl:with-param></xsl:call-template>
+			<xsl:call-template name="Warning"><xsl:with-param name="text">linked <xsl:value-of select="name()"/> "<id><xsl:value-of select="@id"/></id>" has duplicate attribute to linking document. Duplicate ignored.</xsl:with-param></xsl:call-template>
 		</xsl:if>
 	</xsl:for-each>
 	<xsl:if test="*">
-		<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" cannot have both link and content. Content ignored.</xsl:with-param></xsl:call-template>
+		<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<id><xsl:value-of select="@id"/></id>" cannot have both link and content. Content ignored.</xsl:with-param></xsl:call-template>
 	</xsl:if>
 </xsl:if>
 <xsl:if test="@href and name()!=name(document(@href,.)/SystemDefinition/*)">
-		<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" must match item in linked file "<xsl:value-of select="@href"/>"</xsl:with-param></xsl:call-template>
+		<xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<id><xsl:value-of select="@id"/></id>" must match item in linked file "<xsl:value-of select="@href"/>"</xsl:with-param></xsl:call-template>
 </xsl:if>
 <xsl:if test="not(@href)">
 	<xsl:apply-templates select="*">
@@ -293,6 +407,10 @@
 		 </xsl:with-param>
 	</xsl:apply-templates>
 </xsl:if>
+
+<xsl:if test="self::colleciton and not(@level) and ../@levels">
+	<xsl:call-template name="Error"><xsl:with-param name="text">Collection <id><xsl:value-of select="@id"/></id> has no level, despite levels "<xsl:value-of select="../@levels"/>" being defined in <xsl:value-of select="name(..)"/> "<id><xsl:value-of select="../@id"/></id>"</xsl:with-param></xsl:call-template>
+</xsl:if>
 </xsl:template>
 
 
@@ -309,11 +427,62 @@
 	</xsl:apply-templates>
 </xsl:template>
 
+<!-- config metadata -->
+
+<xsl:template match="meta[@rel='config']">	<xsl:param name="filename"/>
+	<xsl:if test="@type!='auto'">
+	<xsl:call-template name="Warning"><xsl:with-param name="text">Unrecognised configuration metadata type <xsl:value-of select="@type"/></xsl:with-param></xsl:call-template>		
+	</xsl:if>
+	<xsl:for-each select="descendant::text()[normalize-space(.)!='']">
+		<xsl:call-template name="Error"><xsl:with-param name="text">Text content not valid in <xsl:value-of select="name(..)"/> (<xsl:value-of select="normalize-space(.)"/>)</xsl:with-param></xsl:call-template>
+	</xsl:for-each>
+	<xsl:if test="pick">
+		<xsl:variable name="npicks" select="count(pick) +1"/>
+		<xsl:for-each select="../descendant-or-self::component">
+			<xsl:if test="count(unit) &gt; $npicks">
+				<xsl:call-template name="Warning"><xsl:with-param name="text">Configuration metadata should have at least one fewer pick elements (<xsl:value-of select="$npicks - 1"/>) than the number of units in <xsl:value-of select="name(..)"/> "<id><xsl:value-of select="../@id"/></id>" (<xsl:value-of select="count(unit)"/>)</xsl:with-param></xsl:call-template>				
+			</xsl:if>
+		</xsl:for-each>
+	</xsl:if>
+	<xsl:apply-templates select="@* | *"/>
+</xsl:template>
+
+
+<xsl:template match="meta[@rel='config']/defined | meta[@rel='config']/not-defined | meta[@rel='config']/pick/defined | meta[@rel='config']/pick/not-defined">
+	<xsl:if test="node()">
+		<xsl:call-template name="Error"><xsl:with-param name="text">Configuration metadata <xsl:value-of select="name()"/> must be empty</xsl:with-param></xsl:call-template>		
+	</xsl:if>
+	<xsl:if test="not(@condition)">
+		<xsl:call-template name="Error"><xsl:with-param name="text">Configuration metadata <xsl:value-of select="name()"/> must have a condition</xsl:with-param></xsl:call-template>		
+	</xsl:if>
+		<xsl:apply-templates select="@*[name()!='condition']" mode="valid"/>
+</xsl:template>
+
+<xsl:template match="meta[@rel='config']/pick">
+	<xsl:choose>
+		<xsl:when test="not(@version)">
+			<xsl:call-template name="Error"><xsl:with-param name="text">Configuration metadata <xsl:value-of select="name()"/> must have a version</xsl:with-param></xsl:call-template>		
+		</xsl:when>
+		<xsl:when test="not(../../descendant::unit[@version=current()/@version])">
+			<xsl:call-template name="Error"><xsl:with-param name="text">Configuration metadata <xsl:value-of select="name()"/> version="<xsl:value-of select="@version"/>" must match a unit within the containing <xsl:value-of select="name(../..)"/> "<xsl:value-of select="../../@id"/>"</xsl:with-param></xsl:call-template>				
+		</xsl:when>
+	</xsl:choose>
+	<xsl:apply-templates select="@*[name()!='version']" mode="valid"/>
+	<xsl:apply-templates select="*"/>
+</xsl:template>
+
+<!-- /config metadata -->
+
+
 
 <xsl:template match="unit/@* | meta/@*" priority="-1">	
 	<xsl:apply-templates select="." mode="valid"/>
 </xsl:template>
 
+<xsl:template match="@*[.='']" mode="valid">
+	<xsl:call-template name="Error"><xsl:with-param name="text">Empty attribute "<xsl:value-of select="name()"/>" on <xsl:value-of select="name(..)"/><xsl:if test="../@id[.!='']"> "<id><xsl:value-of select="../@id"/></id>"</xsl:if></xsl:with-param></xsl:call-template>
+</xsl:template>
+
 
 <xsl:template match="@id" mode="path">
 	<xsl:choose>
@@ -325,13 +494,34 @@
 
 <xsl:template match="@id">
 <xsl:if test="contains(concat(' ',substring-after($all-ids,concat(' ',.,' '))),concat(' ',.,' '))">
-	<xsl:call-template name="Warning"><xsl:with-param name="text">Duplicate ID: <xsl:value-of select="name(..)"/> "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+	<xsl:call-template name="Error"><xsl:with-param name="text">Duplicate ID: <xsl:value-of select="name(..)"/> "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
 </xsl:if>
 
 <xsl:if test="contains(.,':') and not(ancestor::*/namespace::*[name()=substring-before(current(),':')])">
-	<xsl:call-template name="Error"><xsl:with-param name="text">Undefined namespace for ID "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+	<xsl:call-template name="Error"><xsl:with-param name="text">Undefined namespace for ID "<id><xsl:value-of select="."/></id>"</xsl:with-param></xsl:call-template>
+</xsl:if>
+
+<xsl:if test="translate(.,'-','')!=.">
+	<xsl:call-template name="Error"><xsl:with-param name="text">ID "<id><xsl:value-of select="."/></id>" contains reserved character "-" </xsl:with-param></xsl:call-template>
+</xsl:if>
+
+<xsl:if test="contains(.,'.') and not(parent::package) and not(contains(ancestor::pacakge/@id,'.'))">
+	<xsl:call-template name="Error"><xsl:with-param name="text">ID "<xsl:value-of select="."/>" contains reserved character "<code>.</code>" </xsl:with-param></xsl:call-template>
 </xsl:if>
 
+<xsl:if test="translate(substring(.,1,1),'0123456789','')=''">
+	<xsl:call-template name="Error"><xsl:with-param name="text">ID "<id><xsl:value-of select="."/></id>" cannot begin with a digit</xsl:with-param></xsl:call-template>
+</xsl:if>
+
+
+<xsl:if test="translate(.,'&AZ;','')!=.">
+	<xsl:call-template name="Warning"><xsl:with-param name="text">IDs should be entirely in lowercase (<xsl:value-of select="."/>)</xsl:with-param></xsl:call-template>
+</xsl:if>
+
+
+<!-- should also test for outside the range of  Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
+	see http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Name
+ -->
 </xsl:template>
 
 
--- a/metatools/sysdeftools/rootsysdef.pl	Mon Oct 18 10:23:52 2010 +0100
+++ b/metatools/sysdeftools/rootsysdef.pl	Mon Oct 18 10:33:54 2010 +0100
@@ -252,6 +252,10 @@
 	my  ($name,$path) = fileparse($_[0]);
 	if($path eq '' && $name eq '') {return};
 	$path=~tr,\\,/,;
+	if ($path eq './')
+		{
+		return abs_path('.').$name;
+		}
 	if( -e $path)
 		{
 		return abs_path($path)."/$name";