Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Gerwitz <gerwitzm@lovullo.com>2017-07-12 14:26:30 -0400
committerMike Gerwitz <gerwitzm@lovullo.com>2017-07-12 14:32:33 -0400
commit52c1bb5ebe732582606116342730e76aaaba0c55 (patch)
treec20c0102f8f666c5935cbe1a805effa4808a6c52
parent7472cb882c0b2d13d7d8304b805e0a19c7cc38e4 (diff)
downloadtame-52c1bb5ebe732582606116342730e76aaaba0c55.tar.gz
tame-52c1bb5ebe732582606116342730e76aaaba0c55.tar.bz2
tame-52c1bb5ebe732582606116342730e76aaaba0c55.zip
Properly resolve paths of symbols of imports
This solves a long-standing problem whereby relative paths are not properly resolved, leading to incorrect symbol conflicts when relative paths to the same package vary between two imports. See doc/notes/path-processing for an illustration. * src/current/include/preproc/path.xsl (preproc:resolve-relative-import): Add function. (preproc:resolv-path, preproc:resolve-path, preproc:get-path): Add functions to invoke existing templates. * src/current/include/preproc/symtable.xsl (preproc:symimport): Use `preproc:resolve-relative-import'. * doc/notes/path-processing: Add notes.
-rw-r--r--doc/notes/path-processing65
-rw-r--r--src/current/include/preproc/path.xsl71
-rw-r--r--src/current/include/preproc/symtable.xsl40
3 files changed, 149 insertions, 27 deletions
diff --git a/doc/notes/path-processing b/doc/notes/path-processing
new file mode 100644
index 0000000..8560ee0
--- /dev/null
+++ b/doc/notes/path-processing
@@ -0,0 +1,65 @@
+Path processing
+---------------
+Need rules that will work for both the existing scenario (B) and the new
+scenario (A):
+
+
+ _
+ / \
+ / _ \
+ / ___ \
+/_/ \_\
+---------
+
+root = ../
+package = suppliers/colony <--- /suppliers/colony
+import = ../map/return/colony <--- /map/return/colony
+
+mapimport = ../../suppliers/colony/gl <-- /suppliers/colony/gl
+
+
+ this is the root
+ / \
+ v v
+1) <..>/map/return/ | <..>/../suppliers/colony/gl
+ = ../suppliers/colony/gl
+ ^^^^^^^^^^^^^^^^
+ \ /
+ package name
+
+2) strip root||(package base) from package import
+ = ../map/return | <../suppliers/>colony/gl
+ = colony/gl
+ ^^^^^^^^^
+ ` The relative path from package
+
+
+
+ ____
+| __ )
+| _ \
+| |_) |
+|____/
+-------
+
+what about normal includes?
+
+
+root = ../
+package = suppliers/colony <--- /suppliers/colony
+import = ../common/foo <--- /common/foo
+
+subimport = bar/baz <--- /common/foo/bar/baz
+
+
+ one has root, other does not
+ /
+ v
+1) <..>/common/ | bar/baz
+ = ../common/bar/baz
+
+2) strip root||(package base) from package import
+ = ../common/bar/baz
+ ^^^^^^^^^^^^^^^^^
+ ` no such prefix,
+ so this is the relative path
diff --git a/src/current/include/preproc/path.xsl b/src/current/include/preproc/path.xsl
index 14d0cee..6d61147 100644
--- a/src/current/include/preproc/path.xsl
+++ b/src/current/include/preproc/path.xsl
@@ -22,6 +22,7 @@
-->
<stylesheet version="2.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:preproc="http://www.lovullo.com/rater/preproc">
@@ -59,6 +60,15 @@
</template>
+<function name="preproc:get-path" as="xs:string">
+ <param name="path" />
+
+ <call-template name="preproc:get-path">
+ <with-param name="path" select="$path" />
+ </call-template>
+</function>
+
+
<!-- FIXME: duplicate code with above -->
<template name="preproc:get-basename">
<param name="path" />
@@ -94,6 +104,7 @@
</template>
+<!-- TODO: rename to preproc:resolve-path -->
<template name="preproc:resolv-path">
<param name="path" />
@@ -112,6 +123,26 @@
</template>
+<function name="preproc:resolv-path" as="xs:string">
+ <param name="path" />
+
+ <variable name="result" as="xs:string*">
+ <call-template name="preproc:resolv-path">
+ <with-param name="path" select="$path" />
+ </call-template>
+ </variable>
+
+ <sequence select="string-join( $result, '' )" />
+</function>
+
+<!-- alias to the above -->
+<function name="preproc:resolve-path" as="xs:string">
+ <param name="path" />
+
+ <sequence select="preproc:resolv-path( $path )" />
+</function>
+
+
<!-- XXX: warning, this won't like 'foo../' -->
<template name="preproc:resolv-rel-path">
<param name="path" />
@@ -244,4 +275,44 @@
</choose>
</template>
+
+<!--
+ Resolve relative package imports
+
+ This situation arises when a source package (src) imports another
+ package (src-import) that has a reference to an external symbol
+ (sub-import).
+
+ See /doc/notes/path-processing for an illustration.
+-->
+<function name="preproc:resolve-relative-import" as="xs:string">
+ <param name="src-root" as="xs:string" />
+ <param name="src-name" as="xs:string" />
+ <param name="src-import" as="xs:string" />
+ <param name="sub-import" as="xs:string" />
+
+ <variable name="src-prefix" as="xs:string"
+ select="concat( $src-root, '/', $src-name )" />
+
+ <!-- Step 1: resolve relative paths from sub-import -->
+ <variable name="src-import-dir" as="xs:string"
+ select="preproc:get-path( $src-import )" />
+ <variable name="sub-concat" as="xs:string"
+ select="if ( $src-import-dir ) then
+ preproc:resolve-path(
+ concat( $src-import-dir, '/', $sub-import ) )
+ else
+ $sub-import" />
+
+ <!-- Step 2: remove package name prefix, if present -->
+ <variable name="src-name-base" as="xs:string"
+ select="preproc:get-path( $src-name )" />
+ <variable name="src-prefix" as="xs:string"
+ select="concat( $src-root, $src-name-base, '/' )" />
+ <variable name="suffix" as="xs:string"
+ select="substring-after( $sub-concat, $src-prefix )" />
+
+ <sequence select="if ( $suffix ) then $suffix else $sub-concat" />
+</function>
+
</stylesheet>
diff --git a/src/current/include/preproc/symtable.xsl b/src/current/include/preproc/symtable.xsl
index 2cf726c..e9a7c61 100644
--- a/src/current/include/preproc/symtable.xsl
+++ b/src/current/include/preproc/symtable.xsl
@@ -521,12 +521,18 @@
<xsl:param name="no-extclass" select="@no-extclass" />
<xsl:param name="keep-classes" select="@keep-classes" />
- <xsl:variable name="path" select="concat( $package, '.xmlo' )" />
+ <xsl:variable name="path" as="xs:string"
+ select="concat( $package, '.xmlo' )" />
<xsl:variable name="syms"
- select="document( $path, $orig-root )/lv:*/preproc:symtable" />
+ select="document( $path, $orig-root )/lv:*/preproc:symtable" />
<xsl:variable name="import-path" select="$package" />
+ <xsl:variable name="src-root" as="xs:string"
+ select="ancestor::lv:package/@__rootpath" />
+ <xsl:variable name="src-name" as="xs:string"
+ select="ancestor::lv:package/@name" />
+
<!-- if they're including a program package, do they realize what they're
doing!? -->
<!-- FIXME: @allow-nonpkg is no longer accurate terminology; change to
@@ -542,14 +548,6 @@
</xsl:message>
</xsl:if>
- <!-- determine our path from our name -->
- <xsl:variable name="our-path">
- <xsl:call-template name="preproc:get-path">
- <xsl:with-param name="path"
- select="ancestor::lv:package/@name" />
- </xsl:call-template>
- </xsl:variable>
-
<!-- to keep everything consistent and to simplify package equality
assertions, resolve relative paths -->
<xsl:variable name="import-default-path" select="$import-path" />
@@ -626,23 +624,11 @@
itself) onto the existing relative path and resolving relative
paths -->
<xsl:otherwise>
- <xsl:call-template name="preproc:resolv-path">
- <xsl:with-param name="path">
- <!-- get the path of the import, sans package name -->
- <xsl:variable name="path">
- <xsl:call-template name="preproc:get-path">
- <xsl:with-param name="path" select="$import-path" />
- </xsl:call-template>
- </xsl:variable>
-
- <!-- concatenate it with the existing relative path -->
- <xsl:if test="not( $path = '' )">
- <xsl:value-of select="concat( $path, '/' )" />
- </xsl:if>
-
- <xsl:value-of select="@src" />
- </xsl:with-param>
- </xsl:call-template>
+ <xsl:sequence select="preproc:resolve-relative-import(
+ $src-root,
+ $src-name,
+ $import-path,
+ @src )" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>