add `current-library-collection-links' parameter
Also, the initial value causes `curent-library-collection-paths' before collection links files, instead of after.
This commit is contained in:
parent
1468575c3d
commit
8eefa2126b
|
@ -5,29 +5,18 @@
|
||||||
@title[#:tag "collects"]{Libraries and Collections}
|
@title[#:tag "collects"]{Libraries and Collections}
|
||||||
|
|
||||||
A @deftech{library} is @racket[module] declaration for use by multiple
|
A @deftech{library} is @racket[module] declaration for use by multiple
|
||||||
programs. Racket further groups libraries into @deftech{collections}
|
programs. Racket further groups libraries into @deftech{collections}.
|
||||||
that can be easily distributed and added to a local Racket
|
Typically, collections are added via @deftech{packages} (see
|
||||||
installation.
|
@other-doc['(lib "pkg/scribblings/pkg.scrbl")]); the package manager
|
||||||
|
works outside of the Racket core, but it configures the core run-time
|
||||||
|
system through @tech{collection links files}.
|
||||||
|
|
||||||
Some libraries are distributed via @|PLaneT| packages. Such libraries are
|
Libraries in collections are referenced through @racket[lib] paths
|
||||||
referenced through a @racket[planet] module path (see
|
(see @racket[require]) or symbolic shorthands. For example, the
|
||||||
@racket[require]) and are downloaded by Racket on demand.
|
following module uses the @filepath{getinfo.rkt} library module from
|
||||||
|
the @filepath{setup} collection, and the @filepath{cards.rkt} library
|
||||||
Other collections are distributed with Racket, in which case each
|
module from the @filepath{games} collection's @filepath{cards}
|
||||||
collection is a directory that is located in a @filepath{collects}
|
subcollection:
|
||||||
directory relative to the Racket executable. A collection can also be
|
|
||||||
installed in a user-specific directory. More generally, the search
|
|
||||||
path for installed collections can be configured through the
|
|
||||||
@racket[current-library-collection-paths] parameter. Finally, the
|
|
||||||
location of collections can be specified through the @tech{collection
|
|
||||||
links files}; see @secref["links-file"] for more information. In all
|
|
||||||
of these cases, the collections are referenced through @racket[lib]
|
|
||||||
paths (see @racket[require]) or symbolic shorthands.
|
|
||||||
|
|
||||||
For example, the following module uses the @filepath{getinfo.rkt}
|
|
||||||
library module from the @filepath{setup} collection, and the
|
|
||||||
@filepath{cards.rkt} library module from the @filepath{games}
|
|
||||||
collection's @filepath{cards} subcollection:
|
|
||||||
|
|
||||||
@racketmod[
|
@racketmod[
|
||||||
racket
|
racket
|
||||||
|
@ -58,35 +47,137 @@ element that names a library file; the path elements are separated by
|
||||||
@racket[_rel-string] contains @litchar{/} but does not end with a file
|
@racket[_rel-string] contains @litchar{/} but does not end with a file
|
||||||
suffix, then @litchar{.rkt} is implicitly appended to the path.
|
suffix, then @litchar{.rkt} is implicitly appended to the path.
|
||||||
|
|
||||||
|
Libraries also can be distributed via @|PLaneT| packages. Such
|
||||||
|
libraries are referenced through a @racket[planet] module path (see
|
||||||
|
@racket[require]) and are downloaded by Racket on demand, instead of
|
||||||
|
referenced through @tech{collections}.
|
||||||
|
|
||||||
The translation of a @racket[planet] or @racket[lib] path to a
|
The translation of a @racket[planet] or @racket[lib] path to a
|
||||||
@racket[module] declaration is determined by the @tech{module name
|
@racket[module] declaration is determined by the @tech{module name
|
||||||
resolver}, as specified by the @racket[current-module-name-resolver]
|
resolver}, as specified by the @racket[current-module-name-resolver]
|
||||||
parameter.
|
parameter.
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@section[#:tag "collects-search"]{Collection Search Configuration}
|
||||||
|
|
||||||
For the default @tech{module name resolver}, the search path for
|
For the default @tech{module name resolver}, the search path for
|
||||||
collections is determined by the content of the @tech{collection links files}
|
collections is determined by the
|
||||||
and the
|
@racket[current-library-collection-links] parameter and the
|
||||||
@racket[current-library-collection-paths] parameter. The collection
|
@racket[current-library-collection-paths] parameter:
|
||||||
links and then list of paths in
|
|
||||||
@racket[current-library-collection-paths] are searched from first to
|
|
||||||
last to locate the first that contains @racket[_rel-string]. In other
|
|
||||||
words, the filesystem tree for each element in the link table and
|
|
||||||
search path is spliced together with the filesystem trees of other
|
|
||||||
path elements. Some Racket tools rely on unique resolution of module
|
|
||||||
path names, so an installation and
|
|
||||||
@racket[current-library-collection-paths] configuration should not
|
|
||||||
allow multiple files to match the same collection and file name.
|
|
||||||
|
|
||||||
The value of the @racket[current-library-collection-paths] parameter
|
@itemlist[
|
||||||
is initialized in the Racket executable to the result of
|
|
||||||
@racket[(find-library-collection-paths)].
|
|
||||||
|
|
||||||
|
@item{The most primitive @tech{collection}-based modules are located
|
||||||
|
in @filepath{collects} directory relative to the Racket
|
||||||
|
executable. Libraries for a collection are grouped within a
|
||||||
|
directory whose name matches the collection name. The path to
|
||||||
|
the @filepath{collects} directory is normally included in
|
||||||
|
@racket[current-library-collection-paths].}
|
||||||
|
|
||||||
|
@item{Collection-based libraries also can be installed other
|
||||||
|
directories, perhaps user-specific, that are structured like
|
||||||
|
the @filepath{collects} directory. Those additional directories
|
||||||
|
can be included in the
|
||||||
|
@racket[current-library-collection-paths] parameter either
|
||||||
|
dynamically, through command-line arguments to @exec{racket},
|
||||||
|
or by setting the @envvar{PLTCOLLECTS} environment variable;
|
||||||
|
see @racket[find-library-collection-paths].}
|
||||||
|
|
||||||
|
@item{@tech{Collection links files} provide a mapping from top-level
|
||||||
|
collection names to directories, plus additional
|
||||||
|
@filepath{collects}-like directories (that have subdirectories
|
||||||
|
with names that match collection names). Each @tech{collection
|
||||||
|
links file} to be searched is referenced by the
|
||||||
|
@racket[current-library-collection-links] parameter; the parameter
|
||||||
|
references the file, and not the file's content, so
|
||||||
|
that changes to the file can be detected and affect later
|
||||||
|
module resolution. See also
|
||||||
|
@racket[find-library-collection-links].}
|
||||||
|
|
||||||
|
@item{The @racket[current-library-collection-links] parameter's value
|
||||||
|
can also include hash tables that provide the same content as
|
||||||
|
@tech{collection links files}: a mapping from collection names
|
||||||
|
in symbol form to a list of paths for the collection, or from
|
||||||
|
@racket[#f] to a list of @filepath{collects}-like paths.}
|
||||||
|
|
||||||
|
@item{Finally, the @racket[current-library-collection-links]
|
||||||
|
parameter's value includes @racket[#f] to indicate the point in
|
||||||
|
the search process at which the @tech{module-name resolver} should
|
||||||
|
check @racket[current-library-collection-paths] relative to the
|
||||||
|
files and hash tables in @racket[current-library-collection-links].}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
To resolve a module reference @racket[_rel-string], the default
|
||||||
|
@tech{module name resolver} searches collection links in
|
||||||
|
@racket[current-library-collection-links] from first to last to locate
|
||||||
|
the first directory that contains @racket[_rel-string], splicing a
|
||||||
|
search through in @racket[current-library-collection-paths] where in
|
||||||
|
@racket[current-library-collection-links] contains @racket[#f]. The
|
||||||
|
filesystem tree for each element in the link table and search path is
|
||||||
|
effectively spliced together with the filesystem trees of other path
|
||||||
|
elements that correspond to the same collection. Some Racket tools
|
||||||
|
rely on unique resolution of module path names, so an installation and
|
||||||
|
configuration should not allow multiple files to match the same
|
||||||
|
collection and file name.
|
||||||
|
|
||||||
|
The value of the @racket[current-library-collection-links] parameter
|
||||||
|
is initialized by the @exec{racket} executable to the result of
|
||||||
|
@racket[(find-library-collection-links)], and the value of the
|
||||||
|
@racket[current-library-collection-paths] parameter is initialized to
|
||||||
|
the result of @racket[(find-library-collection-paths)].
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@section[#:tag "links-file"]{Collection Links}
|
||||||
|
|
||||||
|
@deftech{Collection links files} are used by
|
||||||
|
@racket[collection-file-path], @racket[collection-path], and the
|
||||||
|
default @tech{module name resolver} to locate collections before
|
||||||
|
trying the @racket[(current-library-collection-paths)] search
|
||||||
|
path. The @tech{collection links files} to use are determined by the
|
||||||
|
@racket[current-library-collection-links] parameter, which is
|
||||||
|
initialized to the result of @racket[find-library-collection-links].
|
||||||
|
|
||||||
|
A @tech{collection links file} is @racket[read] with default reader
|
||||||
|
parameter settings to obtain a list. Every element of the list must be
|
||||||
|
a link specification with one of the forms @racket[(list _string
|
||||||
|
_path)], @racket[(list _string _path _regexp)], @racket[(list 'root
|
||||||
|
_path)], @racket[(list 'root _path _regexp)], @racket[(list 'static-root
|
||||||
|
_path)], @racket[(list 'static-root _path _regexp)]. A @racket[_string] names a
|
||||||
|
top-level @tech{collection}, in which case @racket[_path] is a path
|
||||||
|
that can be used as the collection's path (directly, as opposed to a
|
||||||
|
subdirectory of @racket[_path] named by @racket[_string]). A
|
||||||
|
@racket['root] entry, in contrast, acts like an path in
|
||||||
|
@racket[(current-library-collection-paths)]. A
|
||||||
|
@racket['static-root] entry is like a @racket['root] entry, but
|
||||||
|
where the immediate content of the directory is assumed not to change unless the
|
||||||
|
@tech{collection links file} changes. If @racket[_path] is a
|
||||||
|
relative path, it is relative to the directory containing the
|
||||||
|
@tech{collection links file}. If @racket[_regexp] is specified in a
|
||||||
|
link, then the link is used only if @racket[(regexp-match? _regexp
|
||||||
|
(version))] produces a true result.
|
||||||
|
|
||||||
|
A single top-level collection can have multiple links in a
|
||||||
|
@tech{collection links file}, and any number of @racket['root] entries
|
||||||
|
can appear. The corresponding paths are effectively spliced together,
|
||||||
|
since the paths are tried in order to locate a file or sub-collection.
|
||||||
|
|
||||||
|
The @exec{raco link} command-link tool can display, install, and
|
||||||
|
remove links in a @tech{collection links file}. See @secref[#:doc
|
||||||
|
raco-doc "link"] in @other-manual[raco-doc] for more information.
|
||||||
|
|
||||||
|
@; ----------------------------------------
|
||||||
|
|
||||||
|
@section[#:tag "collects-api"]{Collection Paths and Parameters}
|
||||||
|
|
||||||
@defproc[(find-library-collection-paths [pre-extras (listof path-string?) null]
|
@defproc[(find-library-collection-paths [pre-extras (listof path-string?) null]
|
||||||
[post-extras (listof path-string?) null])
|
[post-extras (listof path-string?) null])
|
||||||
(listof path?)]{
|
(listof path?)]{
|
||||||
|
|
||||||
Produces a list of paths as follows:
|
Produces a list of paths, which is normally used to initialize
|
||||||
|
@racket[current-library-collection-paths], as follows:
|
||||||
|
|
||||||
@itemize[
|
@itemize[
|
||||||
|
|
||||||
|
@ -110,9 +201,11 @@ Produces a list of paths as follows:
|
||||||
|
|
||||||
@item{If the @indexed-envvar{PLTCOLLECTS} environment variable is
|
@item{If the @indexed-envvar{PLTCOLLECTS} environment variable is
|
||||||
defined, it is combined with the default list using
|
defined, it is combined with the default list using
|
||||||
@racket[path-list-string->path-list]. If it is not defined, the
|
@racket[path-list-string->path-list], as long as the value of
|
||||||
default collection path list (as constructed by the first three
|
@racket[use-user-specific-search-paths] is true. If it is not
|
||||||
bullets above) is used directly.
|
defined or if the value @racket[use-user-specific-search-paths] is
|
||||||
|
@racket[#f], the default collection path list (as constructed by the
|
||||||
|
first three bullets above) is used directly.
|
||||||
|
|
||||||
Note that on @|AllUnix|, paths are separated by @litchar{:}, and
|
Note that on @|AllUnix|, paths are separated by @litchar{:}, and
|
||||||
on Windows by @litchar{;}. Also,
|
on Windows by @litchar{;}. Also,
|
||||||
|
@ -124,6 +217,36 @@ Produces a list of paths as follows:
|
||||||
|
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
@defproc[(find-library-collection-links)
|
||||||
|
(listof (or/c #f (and/c path? complete-path?)))]{
|
||||||
|
|
||||||
|
Produces a list of paths and @racket[#f], which is normally used to
|
||||||
|
initialized @racket[current-library-collection-links], as follows:
|
||||||
|
|
||||||
|
@itemlist[
|
||||||
|
|
||||||
|
@item{The list starts with @racket[#f], which causes the default
|
||||||
|
@tech{module name resolver}, @racket[collection-file-path],
|
||||||
|
and @racket[collection-path] to try paths in
|
||||||
|
@racket[current-library-collection-paths] before
|
||||||
|
@tech{collection links files}.}
|
||||||
|
|
||||||
|
@item{As long as the values of
|
||||||
|
@racket[use-user-specific-search-paths] and
|
||||||
|
@racket[use-collection-link-paths] are true, the second element
|
||||||
|
in the result list is the path of the user--specific
|
||||||
|
@tech{collection links file}, which is @racket[(build-path
|
||||||
|
(find-system-path 'addon-dir) (get-installation-name)
|
||||||
|
"links.rktd")].}
|
||||||
|
|
||||||
|
@item{As long as the value of @racket[use-collection-link-paths] is
|
||||||
|
true, the rest of the list contains the result of
|
||||||
|
@racket[get-links-search-files]. Typically, that function
|
||||||
|
produces a list with a single path, @racket[(build-path
|
||||||
|
(find-config-dir) "links.rktd")].}
|
||||||
|
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
@defproc*[([(collection-file-path [file path-string?] [collection path-string?] ...+)
|
@defproc*[([(collection-file-path [file path-string?] [collection path-string?] ...+)
|
||||||
path?]
|
path?]
|
||||||
|
@ -133,7 +256,9 @@ Produces a list of paths as follows:
|
||||||
|
|
||||||
Returns the path to the file indicated by @racket[file] in the
|
Returns the path to the file indicated by @racket[file] in the
|
||||||
collection specified by the @racket[collection]s, where the second
|
collection specified by the @racket[collection]s, where the second
|
||||||
@racket[collection] (if any) names a sub-collection, and so on.
|
@racket[collection] (if any) names a sub-collection, and so on. The
|
||||||
|
search uses the values of @racket[current-library-collection-links]
|
||||||
|
and @racket[current-library-collection-paths].
|
||||||
|
|
||||||
If @racket[file] is not found, but @racket[file] ends in
|
If @racket[file] is not found, but @racket[file] ends in
|
||||||
@filepath{.rkt} and a file with the suffix @filepath{.ss} exists, then
|
@filepath{.rkt} and a file with the suffix @filepath{.ss} exists, then
|
||||||
|
@ -170,8 +295,31 @@ the file level.}
|
||||||
(listof (and/c path? complete-path?))]{
|
(listof (and/c path? complete-path?))]{
|
||||||
|
|
||||||
Parameter that determines a list of complete directory paths for
|
Parameter that determines a list of complete directory paths for
|
||||||
library collections used by @racket[require]. See
|
finding libraries (as referenced in @racket[require], for example)
|
||||||
@secref["collects"] for more information.}
|
through the default @tech{module name resolver} and for finding paths
|
||||||
|
through @racket[collection-path] and
|
||||||
|
@racket[collection-file-path]. See @secref["collects-search"] for more
|
||||||
|
information.}
|
||||||
|
|
||||||
|
|
||||||
|
@defparam*[current-library-collection-links paths
|
||||||
|
(listof (or/c #f
|
||||||
|
(and/c path-string? complete-path?)
|
||||||
|
(hash/c (or/c (and/c symbol? module-path?) #f)
|
||||||
|
(listof (and/c path-string? complete-path?)))))
|
||||||
|
(listof (or/c #f
|
||||||
|
(and/c path? complete-path?)
|
||||||
|
(hash/c (or/c (and/c symbol? module-path?) #f)
|
||||||
|
(listof (and/c path? complete-path?)))))]{
|
||||||
|
|
||||||
|
|
||||||
|
Parameter that determines @tech{collection links files}, additional
|
||||||
|
paths, and the relative search order of
|
||||||
|
@racket[current-library-collection-paths] for finding libraries (as
|
||||||
|
referenced in @racket[require], for example) through the default
|
||||||
|
@tech{module name resolver} and for finding paths through
|
||||||
|
@racket[collection-path] and @racket[collection-file-path]. See
|
||||||
|
@secref["collects-search"] for more information.}
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[use-user-specific-search-paths on?]{
|
@defboolparam[use-user-specific-search-paths on?]{
|
||||||
|
@ -181,12 +329,17 @@ the directory produced by @racket[(find-system-path 'addon-dir)], are
|
||||||
included in search paths for collections and other files. For example,
|
included in search paths for collections and other files. For example,
|
||||||
the initial value of @racket[find-library-collection-paths] omits the
|
the initial value of @racket[find-library-collection-paths] omits the
|
||||||
user-specific collection directory when this parameter's value is
|
user-specific collection directory when this parameter's value is
|
||||||
|
@racket[#f].
|
||||||
|
|
||||||
|
If @Flag{U} or @DFlag{no-user-path} argument to @exec{racket}, then
|
||||||
|
@racket[use-user-specific-search-paths] is initialized to
|
||||||
@racket[#f].}
|
@racket[#f].}
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[use-collection-link-paths on?]{
|
@defboolparam[use-collection-link-paths on?]{
|
||||||
|
|
||||||
Parameter that determines whether @tech{collection links files} are
|
Parameter that determines whether @tech{collection links files} are
|
||||||
used to locate collections.
|
included in the result of @racket[find-library-collection-links].
|
||||||
|
|
||||||
If this parameter's value is @racket[#f] on start-up, then
|
If this parameter's value is @racket[#f] on start-up, then
|
||||||
@tech{collection links files} are effectively disabled permanently for
|
@tech{collection links files} are effectively disabled permanently for
|
||||||
|
@ -196,52 +349,3 @@ only is @racket[current-library-collection-paths] initialized to the
|
||||||
empty list, but @racket[use-collection-link-paths] is initialized to
|
empty list, but @racket[use-collection-link-paths] is initialized to
|
||||||
@racket[#f].}
|
@racket[#f].}
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@section[#:tag "links-file"]{Collection Links}
|
|
||||||
|
|
||||||
The @deftech{collection links files} are used by
|
|
||||||
@racket[collection-file-path], @racket[collection-path], and the
|
|
||||||
default @tech{module name resolver} to locate collections before
|
|
||||||
trying the @racket[(current-library-collection-paths)] search
|
|
||||||
path, but only if the @racket[use-collection-link-paths] parameter is set to
|
|
||||||
@racket[#t]. Furthermore, a user-specific @tech{collection links file} takes
|
|
||||||
precedence over an installation-wide @tech{collection links file}.
|
|
||||||
The user-specific @tech{collection links file} is used only if the
|
|
||||||
@racket[use-user-specific-search-paths] parameter is set to
|
|
||||||
@racket[#t].
|
|
||||||
|
|
||||||
The path of the user--specific @tech{collection links file} is
|
|
||||||
@racket[(build-path (find-system-path 'addon-dir) (get-installation-name) "links.rktd")].
|
|
||||||
The path of the installation-wide @tech{collection links file} is
|
|
||||||
@racket[(build-path (find-config-dir) "links.rktd")].
|
|
||||||
Each @tech{collection links file} is cached by Racket, but
|
|
||||||
the file is re-read if its content changes.
|
|
||||||
|
|
||||||
A @tech{collection links file} is @racket[read] with default reader
|
|
||||||
parameter settings to obtain a list. Every element of the list must be
|
|
||||||
a link specification with one of the forms @racket[(list _string
|
|
||||||
_path)], @racket[(list _string _path _regexp)], @racket[(list 'root
|
|
||||||
_path)], @racket[(list 'root _path _regexp)], @racket[(list 'static-root
|
|
||||||
_path)], @racket[(list 'static-root _path _regexp)]. A @racket[_string] names a
|
|
||||||
top-level @tech{collection}, in which case @racket[_path] is a path
|
|
||||||
that can be used as the collection's path (directly, as opposed to a
|
|
||||||
subdirectory of @racket[_path] named by @racket[_string]). A
|
|
||||||
@racket['root] entry, in contrast, acts like an path in
|
|
||||||
@racket[(current-library-collection-paths)]. A
|
|
||||||
@racket['static-root] entry is like a @racket['root] entry, but
|
|
||||||
where the immediate content of the directory is assumed not to change unless the
|
|
||||||
@tech{collection links file} changes. If @racket[_path] is a
|
|
||||||
relative path, it is relative to the directory containing the
|
|
||||||
@tech{collection links file}. If @racket[_regexp] is specified in a
|
|
||||||
link, then the link is used only if @racket[(regexp-match? _regexp
|
|
||||||
(version))] produces a true result.
|
|
||||||
|
|
||||||
A single top-level collection can have multiple links in a
|
|
||||||
@tech{collection links file}, and any number of @racket['root] entries
|
|
||||||
can appear. The corresponding paths are effectively spliced together,
|
|
||||||
since the paths are tried in order to locate a file or sub-collection.
|
|
||||||
|
|
||||||
The @exec{raco link} command-link tool can display, install, and
|
|
||||||
remove links in the @tech{collection links file}. See @secref[#:doc
|
|
||||||
raco-doc "link"] in @other-manual[raco-doc] for more information.
|
|
||||||
|
|
|
@ -82,6 +82,13 @@ module, the @deftech{module path resolver} is also given the name of
|
||||||
the enclosing module, so that a relative reference can be converted to
|
the enclosing module, so that a relative reference can be converted to
|
||||||
an absolute symbol or @tech{resolved module path}.
|
an absolute symbol or @tech{resolved module path}.
|
||||||
|
|
||||||
|
The default @tech{module name resolver} uses
|
||||||
|
@racket[collection-file-path] to convert @racket[lib] and
|
||||||
|
symbolic-shorthand module paths to filesystem paths. The
|
||||||
|
@racket[collection-file-path] function, in turn, uses the
|
||||||
|
@racket[current-library-collection-links]
|
||||||
|
and @racket[current-library-collection-paths] parameters.
|
||||||
|
|
||||||
A @tech{module name resolver} takes two and four arguments:
|
A @tech{module name resolver} takes two and four arguments:
|
||||||
@itemize[
|
@itemize[
|
||||||
|
|
||||||
|
|
73
pkgs/racket-pkgs/racket-test/tests/racket/collects.rktl
Normal file
73
pkgs/racket-pkgs/racket-test/tests/racket/collects.rktl
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
|
||||||
|
(load-relative "loadtest.rktl")
|
||||||
|
|
||||||
|
(Section 'collects)
|
||||||
|
|
||||||
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(require racket/file)
|
||||||
|
|
||||||
|
(let ()
|
||||||
|
(define tmp-dir (make-temporary-file "collects~a" 'directory))
|
||||||
|
|
||||||
|
(make-directory* (build-path tmp-dir "zjhyq-1"))
|
||||||
|
(with-output-to-file (build-path tmp-dir "zjhyq-1" "m.rkt")
|
||||||
|
(lambda ()
|
||||||
|
(displayln "#lang racket/base")
|
||||||
|
(displayln "(provide v)")
|
||||||
|
(displayln "(define v 1)")))
|
||||||
|
|
||||||
|
(test #f collection-path "zjhyq-1" #:fail (lambda (s) #f))
|
||||||
|
(define (test-found)
|
||||||
|
(test (build-path (build-path tmp-dir "zjhyq-1"))
|
||||||
|
collection-path "zjhyq-1")
|
||||||
|
(test (build-path (build-path tmp-dir "zjhyq-1" "m.rkt"))
|
||||||
|
collection-file-path "m.rkt" "zjhyq-1"))
|
||||||
|
|
||||||
|
;; Add to paths
|
||||||
|
(parameterize ([current-library-collection-paths
|
||||||
|
(append (current-library-collection-paths)
|
||||||
|
(list tmp-dir))])
|
||||||
|
(test-found))
|
||||||
|
|
||||||
|
;; Add to link as hash table from #f:
|
||||||
|
(parameterize ([current-library-collection-links
|
||||||
|
(append (current-library-collection-links)
|
||||||
|
(list (hash #f (list tmp-dir))))])
|
||||||
|
(test-found))
|
||||||
|
|
||||||
|
;; Add to link as hash table from 'zjhyq-1:
|
||||||
|
(parameterize ([current-library-collection-links
|
||||||
|
(append (current-library-collection-links)
|
||||||
|
(list (hash 'zjhyq-1 (list (build-path tmp-dir "zjhyq-1")))))])
|
||||||
|
(test-found))
|
||||||
|
|
||||||
|
(delete-directory/files tmp-dir))
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
|
||||||
|
(err/rt-test (current-library-collection-paths 5))
|
||||||
|
(err/rt-test (current-library-collection-paths (list 5)))
|
||||||
|
(err/rt-test (current-library-collection-paths (list "relative")))
|
||||||
|
;; strings coreced to paths:
|
||||||
|
(test #t andmap path? (parameterize ([current-library-collection-paths (list (path->string
|
||||||
|
(current-directory)))])
|
||||||
|
(current-library-collection-paths)))
|
||||||
|
|
||||||
|
(err/rt-test (current-library-collection-links 5))
|
||||||
|
(err/rt-test (current-library-collection-links (list 5)))
|
||||||
|
(err/rt-test (current-library-collection-links (list #t)))
|
||||||
|
(err/rt-test (current-library-collection-links (list "relative")))
|
||||||
|
(err/rt-test (current-library-collection-links (list (hash 'bad! null))))
|
||||||
|
(err/rt-test (current-library-collection-links (list (hash 'ok 5))))
|
||||||
|
(err/rt-test (current-library-collection-links (list (hash 'ok (list 5)))))
|
||||||
|
(err/rt-test (current-library-collection-links (list (hash 'ok (list "relative")))))
|
||||||
|
;; strings coreced to paths:
|
||||||
|
(test #t andmap path? (parameterize ([current-library-collection-links (list (path->string
|
||||||
|
(build-path (current-directory)
|
||||||
|
"links.rktd")))])
|
||||||
|
(current-library-collection-links)))
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
|
||||||
|
(report-errs)
|
|
@ -27,6 +27,7 @@
|
||||||
(load-relative "prompt.rktl")
|
(load-relative "prompt.rktl")
|
||||||
(load-relative "will.rktl")
|
(load-relative "will.rktl")
|
||||||
(load-relative "namespac.rktl")
|
(load-relative "namespac.rktl")
|
||||||
|
(load-relative "collects.rktl")
|
||||||
(load-relative "modprot.rktl")
|
(load-relative "modprot.rktl")
|
||||||
(load-relative "chaperone.rktl")
|
(load-relative "chaperone.rktl")
|
||||||
(unless (or building-flat-tests? in-drscheme?)
|
(unless (or building-flat-tests? in-drscheme?)
|
||||||
|
|
|
@ -923,24 +923,25 @@
|
||||||
(current-library-collection-paths)))]
|
(current-library-collection-paths)))]
|
||||||
[sandbox-path-permissions
|
[sandbox-path-permissions
|
||||||
`(,@(map (lambda (p) `(read-bytecode ,p))
|
`(,@(map (lambda (p) `(read-bytecode ,p))
|
||||||
|
(apply
|
||||||
|
append
|
||||||
|
(for/list ([l (current-library-collection-links)])
|
||||||
|
(cond
|
||||||
|
[(not l)
|
||||||
|
(current-library-collection-paths)]
|
||||||
|
[(hash? l)
|
||||||
|
(hash-values l)]
|
||||||
|
[else
|
||||||
|
(if (file-exists? l)
|
||||||
(append
|
(append
|
||||||
(current-library-collection-paths)
|
(links #:root? #t #:file l)
|
||||||
(apply append
|
(map cdr (links #:file l #:with-path? #t)))
|
||||||
(for/list ([f (get-links-search-files)]
|
null)]))))
|
||||||
#:when (file-exists? f))
|
,@(for/list ([l (current-library-collection-links)]
|
||||||
(links #:root? #t #:file f)))
|
#:when (path? l))
|
||||||
(links #:root? #t #:user? #t)
|
`(read ,l))
|
||||||
(apply append
|
|
||||||
(for/list ([f (get-links-search-files)]
|
|
||||||
#:when (file-exists? f))
|
|
||||||
(map cdr (links #:file f #:with-path? #t))))
|
|
||||||
(map cdr (links #:user? #t #:with-path? #t))))
|
|
||||||
(read-bytecode ,(PLANET-BASE-DIR))
|
(read-bytecode ,(PLANET-BASE-DIR))
|
||||||
(exists ,(find-system-path 'addon-dir))
|
(exists ,(find-system-path 'addon-dir))
|
||||||
(read ,(build-path (find-system-path 'addon-dir) "links.rktd"))
|
|
||||||
(read ,(build-path (find-system-path 'addon-dir) (version) "links.rktd"))
|
|
||||||
,@(for/list ([f (get-links-search-files)])
|
|
||||||
`(read ,f))
|
|
||||||
(read ,(find-lib-dir))
|
(read ,(find-lib-dir))
|
||||||
,@(compute-permissions allow-for-require allow-for-load)
|
,@(compute-permissions allow-for-require allow-for-load)
|
||||||
,@(sandbox-path-permissions))]
|
,@(sandbox-path-permissions))]
|
||||||
|
|
|
@ -9,24 +9,22 @@
|
||||||
(hash-set s (path-element->string p) #t))
|
(hash-set s (path-element->string p) #t))
|
||||||
s))
|
s))
|
||||||
|
|
||||||
(define (links* m root?)
|
|
||||||
(case m
|
|
||||||
[(user) (links #:user? #t #:root? root?)]
|
|
||||||
[else (links #:file m #:root? root?)]))
|
|
||||||
|
|
||||||
(define (get-all-top-level-collections)
|
(define (get-all-top-level-collections)
|
||||||
(define link-modes (list* 'user (get-links-search-files)))
|
(hash-keys
|
||||||
|
(for/fold ([s (hash)]) ([l (in-list
|
||||||
(let* ([s (hash)]
|
(current-library-collection-links))])
|
||||||
[s (for/fold ([s s]) ([c (in-list
|
(cond
|
||||||
|
[(not l)
|
||||||
|
(for/fold ([s s]) ([c (in-list
|
||||||
(current-library-collection-paths))])
|
(current-library-collection-paths))])
|
||||||
(add-directory-collections c s))]
|
(add-directory-collections c s))]
|
||||||
[s (for*/fold ([s s]) ([m (in-list link-modes)]
|
[(path? l)
|
||||||
[l (in-list (links* m #f))])
|
(let ([s (for*/fold ([s s]) ([c (in-list (links #:file l #:root? #f))])
|
||||||
(hash-set s l #t))]
|
(hash-set s c #t))])
|
||||||
[s (for*/fold ([s s]) ([m (in-list link-modes)]
|
(for*/fold ([s s]) ([c (in-list (links #:file l #:root? #t))])
|
||||||
[c (in-list (links* m #t))])
|
(add-directory-collections c s)))]
|
||||||
(add-directory-collections c s))])
|
[else (error 'get-all-top-level-collections
|
||||||
(hash-keys s)))
|
"unexpected value in `current-library-collection-links': ~e"
|
||||||
|
l)]))))
|
||||||
|
|
||||||
(for-each displayln (get-all-top-level-collections))
|
(for-each displayln (get-all-top-level-collections))
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
Version 5.90.0.4
|
||||||
|
Add current-library-collection-links, find-library-collection-links
|
||||||
|
Changed module search to use current-library-collection-paths
|
||||||
|
before collection link files by default
|
||||||
|
Changed use-user-specific-search-paths and use-collection-link-paths
|
||||||
|
to affect only find-library-collection-paths and
|
||||||
|
find-library-collection-links
|
||||||
|
|
||||||
Version 5.90.0.3
|
Version 5.90.0.3
|
||||||
Base user directoy paths on an installation name instead
|
Base user directoy paths on an installation name instead
|
||||||
of the Racket version string
|
of the Racket version string
|
||||||
|
|
|
@ -234,6 +234,7 @@
|
||||||
guard-evt channel-get channel-try-get channel-put
|
guard-evt channel-get channel-try-get channel-put
|
||||||
port? displayln
|
port? displayln
|
||||||
find-library-collection-paths
|
find-library-collection-paths
|
||||||
|
find-library-collection-links
|
||||||
bytes-environment-variable-name?
|
bytes-environment-variable-name?
|
||||||
string-environment-variable-name?
|
string-environment-variable-name?
|
||||||
getenv putenv
|
getenv putenv
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
(define main-collects-dir (simple-form-path (find-collects-dir)))
|
(define main-collects-dir (simple-form-path (find-collects-dir)))
|
||||||
(define main-collects-dirs (for/hash ([p (in-list (get-main-collects-search-dirs))])
|
(define main-collects-dirs (for/hash ([p (in-list (get-main-collects-search-dirs))])
|
||||||
(values (simple-form-path p) #t)))
|
(values (simple-form-path p) #t)))
|
||||||
|
(define main-links-files (for/hash ([p (in-list (get-links-search-files))])
|
||||||
|
(values (simple-form-path p) #t)))
|
||||||
(define mode-dir
|
(define mode-dir
|
||||||
(if (compile-mode)
|
(if (compile-mode)
|
||||||
(build-path "compiled" (compile-mode))
|
(build-path "compiled" (compile-mode))
|
||||||
|
@ -76,7 +78,12 @@
|
||||||
p)))
|
p)))
|
||||||
|
|
||||||
(current-library-collection-paths
|
(current-library-collection-paths
|
||||||
(map simple-form-path (current-library-collection-paths)))
|
(if (member #f (current-library-collection-links))
|
||||||
|
;; Normal case, include current library collection paths:
|
||||||
|
(map simple-form-path (current-library-collection-paths))
|
||||||
|
;; No `#f' in links list means that we don't look at
|
||||||
|
;; the current library collection paths:
|
||||||
|
null))
|
||||||
|
|
||||||
(define (setup-fprintf p task s . args)
|
(define (setup-fprintf p task s . args)
|
||||||
(let ([task (if task (string-append task ": ") "")])
|
(let ([task (if task (string-append task ": ") "")])
|
||||||
|
@ -345,7 +352,8 @@
|
||||||
;; checkout as a collection directory
|
;; checkout as a collection directory
|
||||||
(regexp-match? #rx"[.](git|svn)$" (path->bytes collection)))
|
(regexp-match? #rx"[.](git|svn)$" (path->bytes collection)))
|
||||||
|
|
||||||
;; Add in all non-planet collections:
|
;; Add in all non-planet collections, first from
|
||||||
|
;; `current-library-collection-paths':
|
||||||
(for ([cp (current-library-collection-paths)]
|
(for ([cp (current-library-collection-paths)]
|
||||||
#:when (directory-exists? cp)
|
#:when (directory-exists? cp)
|
||||||
[collection (directory-list cp)]
|
[collection (directory-list cp)]
|
||||||
|
@ -355,6 +363,8 @@
|
||||||
#:info-root cp
|
#:info-root cp
|
||||||
#:path (build-path cp collection)
|
#:path (build-path cp collection)
|
||||||
#:main? (hash-ref main-collects-dirs cp #f)))
|
#:main? (hash-ref main-collects-dirs cp #f)))
|
||||||
|
;; Now from `current-library-collection-links' for installation-wide
|
||||||
|
;; links:
|
||||||
(let ()
|
(let ()
|
||||||
(define info-root (find-share-dir))
|
(define info-root (find-share-dir))
|
||||||
(define info-path (build-path info-root "info-cache.rktd"))
|
(define info-path (build-path info-root "info-cache.rktd"))
|
||||||
|
@ -366,7 +376,9 @@
|
||||||
#:info-path-mode 'abs-in-relative
|
#:info-path-mode 'abs-in-relative
|
||||||
#:omit-root 'dir
|
#:omit-root 'dir
|
||||||
#:main? #t))
|
#:main? #t))
|
||||||
(for ([inst-links (in-list (get-links-search-files))])
|
(for ([inst-links (in-list (current-library-collection-links))]
|
||||||
|
#:when (and (path? inst-links)
|
||||||
|
(hash-ref main-links-files (simple-form-path inst-links) #f)))
|
||||||
(for ([c+p (in-list (links #:file inst-links #:with-path? #t))])
|
(for ([c+p (in-list (links #:file inst-links #:with-path? #t))])
|
||||||
(cc! (list (string->path (car c+p)))
|
(cc! (list (string->path (car c+p)))
|
||||||
#:path (cdr c+p)))
|
#:path (cdr c+p)))
|
||||||
|
@ -377,6 +389,8 @@
|
||||||
#:when (directory-exists? (build-path cp collection)))
|
#:when (directory-exists? (build-path cp collection)))
|
||||||
(cc! (list collection)
|
(cc! (list collection)
|
||||||
#:path (build-path cp collection)))))
|
#:path (build-path cp collection)))))
|
||||||
|
;; Now from `current-library-collection-links' for user-specific
|
||||||
|
;; links:
|
||||||
(when (make-user)
|
(when (make-user)
|
||||||
(define info-root (find-user-share-dir))
|
(define info-root (find-user-share-dir))
|
||||||
(define info-path (build-path info-root "info-cache.rktd"))
|
(define info-path (build-path info-root "info-cache.rktd"))
|
||||||
|
@ -387,15 +401,36 @@
|
||||||
#:info-path info-path
|
#:info-path info-path
|
||||||
#:info-path-mode 'abs-in-relative
|
#:info-path-mode 'abs-in-relative
|
||||||
#:omit-root 'dir))
|
#:omit-root 'dir))
|
||||||
(for ([c+p (in-list (links #:with-path? #t))])
|
;; A links spec in `current-library-collection-links' counts as
|
||||||
|
;; user-specific when it's not in `make-links-files':
|
||||||
|
(for ([inst-links (in-list (current-library-collection-links))]
|
||||||
|
#:unless (and (path? inst-links)
|
||||||
|
(hash-ref main-links-files (simple-form-path inst-links) #f)))
|
||||||
|
(cond
|
||||||
|
[(not inst-links) ; covered by `current-library-collection-paths'
|
||||||
|
(void)]
|
||||||
|
[(path? inst-links)
|
||||||
|
(for ([c+p (in-list (links #:file inst-links #:with-path? #t))])
|
||||||
(cc! (list (string->path (car c+p)))
|
(cc! (list (string->path (car c+p)))
|
||||||
#:path (cdr c+p)))
|
#:path (cdr c+p)))
|
||||||
(for ([cp (in-list (links #:root? #t))]
|
(for ([cp (in-list (links #:file inst-links #:root? #t))]
|
||||||
#:when (directory-exists? cp)
|
#:when (directory-exists? cp)
|
||||||
[collection (directory-list cp)]
|
[collection (directory-list cp)]
|
||||||
#:unless (skip-collection-directory? collection)
|
#:unless (skip-collection-directory? collection)
|
||||||
#:when (directory-exists? (build-path cp collection)))
|
#:when (directory-exists? (build-path cp collection)))
|
||||||
(cc! (list collection) #:path (build-path cp collection))))
|
(cc! (list collection) #:path (build-path cp collection)))]
|
||||||
|
[else ; must be a hash table that simulates a links file:
|
||||||
|
(for ([(coll-sym dir) (in-hash inst-links)])
|
||||||
|
(cond
|
||||||
|
[coll-sym
|
||||||
|
;; A single collection
|
||||||
|
(cc! (string-split "/" (symbol->string coll-sym)) #:path dir)]
|
||||||
|
[(directory-exists? dir)
|
||||||
|
;; A directory that holds collections:
|
||||||
|
(for ([collection (directory-list dir)]
|
||||||
|
#:unless (skip-collection-directory? collection)
|
||||||
|
#:when (directory-exists? (build-path dir collection)))
|
||||||
|
(cc! (list collection) #:path (build-path dir collection)))]))])))
|
||||||
|
|
||||||
;; `all-collections' lists all top-level collections (not from Planet):
|
;; `all-collections' lists all top-level collections (not from Planet):
|
||||||
(define all-collections
|
(define all-collections
|
||||||
|
|
|
@ -1360,6 +1360,7 @@ enum {
|
||||||
MZCONFIG_WRITE_DIRECTORY,
|
MZCONFIG_WRITE_DIRECTORY,
|
||||||
|
|
||||||
MZCONFIG_COLLECTION_PATHS,
|
MZCONFIG_COLLECTION_PATHS,
|
||||||
|
MZCONFIG_COLLECTION_LINKS,
|
||||||
|
|
||||||
MZCONFIG_PORT_PRINT_HANDLER,
|
MZCONFIG_PORT_PRINT_HANDLER,
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,6 @@ typedef struct Thread_Local_Variables {
|
||||||
int env_uid_counter_;
|
int env_uid_counter_;
|
||||||
int scheme_overflow_count_;
|
int scheme_overflow_count_;
|
||||||
struct Scheme_Object *original_pwd_;
|
struct Scheme_Object *original_pwd_;
|
||||||
struct Scheme_Object *inst_links_path_;
|
|
||||||
void *file_path_wc_buffer_;
|
void *file_path_wc_buffer_;
|
||||||
intptr_t scheme_hash_request_count_;
|
intptr_t scheme_hash_request_count_;
|
||||||
intptr_t scheme_hash_iteration_count_;
|
intptr_t scheme_hash_iteration_count_;
|
||||||
|
@ -665,7 +664,6 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
|
||||||
#define env_uid_counter XOA (scheme_get_thread_local_variables()->env_uid_counter_)
|
#define env_uid_counter XOA (scheme_get_thread_local_variables()->env_uid_counter_)
|
||||||
#define scheme_overflow_count XOA (scheme_get_thread_local_variables()->scheme_overflow_count_)
|
#define scheme_overflow_count XOA (scheme_get_thread_local_variables()->scheme_overflow_count_)
|
||||||
#define original_pwd XOA (scheme_get_thread_local_variables()->original_pwd_)
|
#define original_pwd XOA (scheme_get_thread_local_variables()->original_pwd_)
|
||||||
#define inst_links_path XOA (scheme_get_thread_local_variables()->inst_links_path_)
|
|
||||||
#define file_path_wc_buffer XOA (scheme_get_thread_local_variables()->file_path_wc_buffer_)
|
#define file_path_wc_buffer XOA (scheme_get_thread_local_variables()->file_path_wc_buffer_)
|
||||||
#define scheme_hash_request_count XOA (scheme_get_thread_local_variables()->scheme_hash_request_count_)
|
#define scheme_hash_request_count XOA (scheme_get_thread_local_variables()->scheme_hash_request_count_)
|
||||||
#define scheme_hash_iteration_count XOA (scheme_get_thread_local_variables()->scheme_hash_iteration_count_)
|
#define scheme_hash_iteration_count XOA (scheme_get_thread_local_variables()->scheme_hash_iteration_count_)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5325,6 +5325,14 @@ void scheme_init_collection_paths_post(Scheme_Env *global_env, Scheme_Object *ex
|
||||||
if (!scheme_setjmp(newbuf)) {
|
if (!scheme_setjmp(newbuf)) {
|
||||||
Scheme_Object *clcp, *flcp, *a[2];
|
Scheme_Object *clcp, *flcp, *a[2];
|
||||||
|
|
||||||
|
clcp = scheme_builtin_value("current-library-collection-links");
|
||||||
|
flcp = scheme_builtin_value("find-library-collection-links");
|
||||||
|
|
||||||
|
if (clcp && flcp) {
|
||||||
|
a[0] = _scheme_apply(flcp, 0, NULL);
|
||||||
|
_scheme_apply(clcp, 1, a);
|
||||||
|
}
|
||||||
|
|
||||||
clcp = scheme_builtin_value("current-library-collection-paths");
|
clcp = scheme_builtin_value("current-library-collection-paths");
|
||||||
flcp = scheme_builtin_value("find-library-collection-paths");
|
flcp = scheme_builtin_value("find-library-collection-paths");
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,7 @@ static Scheme_Object *file_or_dir_permissions(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *file_identity(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *file_identity(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *file_size(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *file_size(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *current_library_collection_paths(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *current_library_collection_paths(int argc, Scheme_Object *argv[]);
|
||||||
|
static Scheme_Object *current_library_collection_links(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *use_compiled_kind(int, Scheme_Object *[]);
|
static Scheme_Object *use_compiled_kind(int, Scheme_Object *[]);
|
||||||
static Scheme_Object *compiled_file_roots(int, Scheme_Object *[]);
|
static Scheme_Object *compiled_file_roots(int, Scheme_Object *[]);
|
||||||
static Scheme_Object *use_user_paths(int, Scheme_Object *[]);
|
static Scheme_Object *use_user_paths(int, Scheme_Object *[]);
|
||||||
|
@ -240,7 +241,6 @@ SHARED_OK static Scheme_Object *run_cmd;
|
||||||
SHARED_OK static Scheme_Object *collects_path, *config_path;
|
SHARED_OK static Scheme_Object *collects_path, *config_path;
|
||||||
THREAD_LOCAL_DECL(static Scheme_Object *original_pwd);
|
THREAD_LOCAL_DECL(static Scheme_Object *original_pwd);
|
||||||
SHARED_OK static Scheme_Object *addon_dir;
|
SHARED_OK static Scheme_Object *addon_dir;
|
||||||
THREAD_LOCAL_DECL(static Scheme_Object *inst_links_path);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
READ_ONLY static Scheme_Object *windows_symbol, *unix_symbol;
|
READ_ONLY static Scheme_Object *windows_symbol, *unix_symbol;
|
||||||
|
@ -554,6 +554,11 @@ void scheme_init_file(Scheme_Env *env)
|
||||||
"current-library-collection-paths",
|
"current-library-collection-paths",
|
||||||
MZCONFIG_COLLECTION_PATHS),
|
MZCONFIG_COLLECTION_PATHS),
|
||||||
env);
|
env);
|
||||||
|
scheme_add_global_constant("current-library-collection-links",
|
||||||
|
scheme_register_parameter(current_library_collection_links,
|
||||||
|
"current-library-collection-links",
|
||||||
|
MZCONFIG_COLLECTION_LINKS),
|
||||||
|
env);
|
||||||
#endif
|
#endif
|
||||||
scheme_add_global_constant("use-compiled-file-paths",
|
scheme_add_global_constant("use-compiled-file-paths",
|
||||||
scheme_register_parameter(use_compiled_kind,
|
scheme_register_parameter(use_compiled_kind,
|
||||||
|
@ -5930,9 +5935,38 @@ static Scheme_Object *current_user_directory(int argc, Scheme_Object **argv)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Scheme_Object *collpaths_gen_p(int argc, Scheme_Object **argv, int rel_ok, int abs_ok, int sym_ok)
|
static Scheme_Object *check_link_key_val(Scheme_Object *key, Scheme_Object *val)
|
||||||
|
{
|
||||||
|
Scheme_Object *new_val = scheme_null, *a;
|
||||||
|
|
||||||
|
if (!SCHEME_FALSEP(key)
|
||||||
|
&& (!SCHEME_SYMBOLP(key)
|
||||||
|
|| !scheme_is_module_path(key)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (SCHEME_PAIRP(val)) {
|
||||||
|
a = SCHEME_CAR(val);
|
||||||
|
if (!SCHEME_PATH_STRINGP(a))
|
||||||
|
return NULL;
|
||||||
|
a = TO_PATH(a);
|
||||||
|
if (!scheme_is_complete_path(SCHEME_PATH_VAL(a),
|
||||||
|
SCHEME_PATH_LEN(a),
|
||||||
|
SCHEME_PLATFORM_PATH_KIND))
|
||||||
|
return NULL;
|
||||||
|
new_val = scheme_make_pair(a, new_val);
|
||||||
|
val = SCHEME_CDR(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SCHEME_NULLP(val))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return scheme_reverse(new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *collpaths_gen_p(int argc, Scheme_Object **argv, int rel_ok, int abs_ok, int sym_ok, int links_ok)
|
||||||
{
|
{
|
||||||
Scheme_Object *v = argv[0];
|
Scheme_Object *v = argv[0];
|
||||||
|
Scheme_Object *new_hts = scheme_null;
|
||||||
|
|
||||||
if (scheme_proper_list_length(v) < 0)
|
if (scheme_proper_list_length(v) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5945,6 +5979,36 @@ static Scheme_Object *collpaths_gen_p(int argc, Scheme_Object **argv, int rel_ok
|
||||||
s = SCHEME_CAR(v);
|
s = SCHEME_CAR(v);
|
||||||
if (sym_ok && SAME_OBJ(s, same_symbol)) {
|
if (sym_ok && SAME_OBJ(s, same_symbol)) {
|
||||||
/* ok */
|
/* ok */
|
||||||
|
} else if (links_ok && SCHEME_FALSEP(s)) {
|
||||||
|
/* ok */
|
||||||
|
} else if (links_ok && (SCHEME_CHAPERONE_HASHTP(s)
|
||||||
|
|| SCHEME_CHAPERONE_HASHTRP(s)
|
||||||
|
|| SCHEME_CHAPERONE_BUCKTP(s))) {
|
||||||
|
Scheme_Hash_Tree *new_ht;
|
||||||
|
Scheme_Object *key, *val, *idx, *a[2];
|
||||||
|
|
||||||
|
new_ht = scheme_make_hash_tree(0);
|
||||||
|
|
||||||
|
a[0] = s;
|
||||||
|
idx = scheme_hash_table_iterate_start(1, a);
|
||||||
|
while (SCHEME_TRUEP(idx)) {
|
||||||
|
a[0] = s;
|
||||||
|
a[1] = idx;
|
||||||
|
key = scheme_hash_table_iterate_key(2, a);
|
||||||
|
|
||||||
|
val = scheme_chaperone_hash_get(s, key);
|
||||||
|
if (val) {
|
||||||
|
val = check_link_key_val(key, val);
|
||||||
|
if (!val) return NULL;
|
||||||
|
new_ht = scheme_hash_tree_set(new_ht, key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
a[0] = s;
|
||||||
|
a[1] = idx;
|
||||||
|
idx = scheme_hash_table_iterate_next(2, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_hts = scheme_make_pair((Scheme_Object *)new_ht, new_hts);
|
||||||
} else {
|
} else {
|
||||||
if (!SCHEME_PATH_STRINGP(s))
|
if (!SCHEME_PATH_STRINGP(s))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5964,14 +6028,24 @@ static Scheme_Object *collpaths_gen_p(int argc, Scheme_Object **argv, int rel_ok
|
||||||
if (!SCHEME_NULLP(v))
|
if (!SCHEME_NULLP(v))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
new_hts = scheme_reverse(new_hts);
|
||||||
|
|
||||||
/* Convert to list of paths: */
|
/* Convert to list of paths: */
|
||||||
{
|
{
|
||||||
Scheme_Object *last = NULL, *first = NULL, *p, *s;
|
Scheme_Object *last = NULL, *first = NULL, *p, *s;
|
||||||
v = argv[0];
|
v = argv[0];
|
||||||
while (SCHEME_PAIRP(v)) {
|
while (SCHEME_PAIRP(v)) {
|
||||||
s = SCHEME_CAR(v);
|
s = SCHEME_CAR(v);
|
||||||
if (!SCHEME_SYMBOLP(s))
|
if (SCHEME_SYMBOLP(s)) {
|
||||||
|
/* ok */
|
||||||
|
} else if (SCHEME_FALSEP(s)) {
|
||||||
|
/* ok */
|
||||||
|
} else if (SCHEME_PATH_STRINGP(s)) {
|
||||||
s = TO_PATH(s);
|
s = TO_PATH(s);
|
||||||
|
} else {
|
||||||
|
s = SCHEME_CAR(new_hts);
|
||||||
|
new_hts = SCHEME_CDR(new_hts);
|
||||||
|
}
|
||||||
|
|
||||||
p = scheme_make_pair(s, scheme_null);
|
p = scheme_make_pair(s, scheme_null);
|
||||||
if (!first)
|
if (!first)
|
||||||
|
@ -5991,7 +6065,7 @@ static Scheme_Object *collpaths_gen_p(int argc, Scheme_Object **argv, int rel_ok
|
||||||
|
|
||||||
static Scheme_Object *collpaths_p(int argc, Scheme_Object **argv)
|
static Scheme_Object *collpaths_p(int argc, Scheme_Object **argv)
|
||||||
{
|
{
|
||||||
return collpaths_gen_p(argc, argv, 0, 1, 0);
|
return collpaths_gen_p(argc, argv, 0, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme_Object *scheme_current_library_collection_paths(int argc, Scheme_Object *argv[]) {
|
Scheme_Object *scheme_current_library_collection_paths(int argc, Scheme_Object *argv[]) {
|
||||||
|
@ -6006,11 +6080,32 @@ static Scheme_Object *current_library_collection_paths(int argc, Scheme_Object *
|
||||||
-1, collpaths_p, "(listof (and/c path-string? complete-path?))", 1);
|
-1, collpaths_p, "(listof (and/c path-string? complete-path?))", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *colllinks_p(int argc, Scheme_Object **argv)
|
||||||
|
{
|
||||||
|
return collpaths_gen_p(argc, argv, 0, 1, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scheme_Object *scheme_current_library_collection_links(int argc, Scheme_Object *argv[]) {
|
||||||
|
return current_library_collection_links(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *current_library_collection_links(int argc, Scheme_Object *argv[])
|
||||||
|
{
|
||||||
|
return scheme_param_config2("current-library-collection-links",
|
||||||
|
scheme_make_integer(MZCONFIG_COLLECTION_LINKS),
|
||||||
|
argc, argv,
|
||||||
|
-1, colllinks_p,
|
||||||
|
"(listof (or/c #f (and/c path-string? complete-path?)"
|
||||||
|
/**/ " (hash/c (or/c (and/c symbol? module-path?) #f)"
|
||||||
|
/**/ " (listof (and/c path-string? complete-path?)))))",
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Scheme_Object *compiled_kind_p(int argc, Scheme_Object **argv)
|
static Scheme_Object *compiled_kind_p(int argc, Scheme_Object **argv)
|
||||||
{
|
{
|
||||||
return collpaths_gen_p(argc, argv, 1, 0, 0);
|
return collpaths_gen_p(argc, argv, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *use_compiled_kind(int argc, Scheme_Object *argv[])
|
static Scheme_Object *use_compiled_kind(int argc, Scheme_Object *argv[])
|
||||||
|
@ -6023,7 +6118,7 @@ static Scheme_Object *use_compiled_kind(int argc, Scheme_Object *argv[])
|
||||||
|
|
||||||
static Scheme_Object *compiled_roots_p(int argc, Scheme_Object **argv)
|
static Scheme_Object *compiled_roots_p(int argc, Scheme_Object **argv)
|
||||||
{
|
{
|
||||||
return collpaths_gen_p(argc, argv, 1, 1, 1);
|
return collpaths_gen_p(argc, argv, 1, 1, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme_Object *scheme_compiled_file_roots(int argc, Scheme_Object *argv[])
|
Scheme_Object *scheme_compiled_file_roots(int argc, Scheme_Object *argv[])
|
||||||
|
@ -6438,17 +6533,6 @@ void scheme_set_addon_dir(Scheme_Object *p)
|
||||||
addon_dir = p;
|
addon_dir = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme_Object *scheme_find_links_path(int argc, Scheme_Object *argv[])
|
|
||||||
{
|
|
||||||
if (inst_links_path)
|
|
||||||
return inst_links_path;
|
|
||||||
|
|
||||||
REGISTER_SO(inst_links_path);
|
|
||||||
inst_links_path = scheme_apply(argv[0], 0, NULL);
|
|
||||||
|
|
||||||
return inst_links_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
|
|
||||||
#ifdef DOS_FILE_SYSTEM
|
#ifdef DOS_FILE_SYSTEM
|
||||||
|
|
|
@ -208,6 +208,7 @@ typedef struct Place_Start_Data {
|
||||||
Scheme_Object *function;
|
Scheme_Object *function;
|
||||||
Scheme_Object *channel;
|
Scheme_Object *channel;
|
||||||
Scheme_Object *current_library_collection_paths;
|
Scheme_Object *current_library_collection_paths;
|
||||||
|
Scheme_Object *current_library_collection_links;
|
||||||
Scheme_Object *compiled_roots;
|
Scheme_Object *compiled_roots;
|
||||||
mzrt_sema *ready; /* malloc'ed item */
|
mzrt_sema *ready; /* malloc'ed item */
|
||||||
struct Scheme_Place_Object *place_obj; /* malloc'ed item */
|
struct Scheme_Place_Object *place_obj; /* malloc'ed item */
|
||||||
|
@ -274,6 +275,7 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) {
|
||||||
Place_Start_Data *place_data;
|
Place_Start_Data *place_data;
|
||||||
mz_proc_thread *proc_thread;
|
mz_proc_thread *proc_thread;
|
||||||
Scheme_Object *collection_paths;
|
Scheme_Object *collection_paths;
|
||||||
|
Scheme_Object *collection_links;
|
||||||
Scheme_Place_Object *place_obj;
|
Scheme_Place_Object *place_obj;
|
||||||
mzrt_sema *ready;
|
mzrt_sema *ready;
|
||||||
struct NewGC *parent_gc;
|
struct NewGC *parent_gc;
|
||||||
|
@ -364,6 +366,9 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) {
|
||||||
collection_paths = scheme_current_library_collection_paths(0, NULL);
|
collection_paths = scheme_current_library_collection_paths(0, NULL);
|
||||||
place_data->current_library_collection_paths = collection_paths;
|
place_data->current_library_collection_paths = collection_paths;
|
||||||
|
|
||||||
|
collection_links = scheme_current_library_collection_links(0, NULL);
|
||||||
|
place_data->current_library_collection_links = collection_links;
|
||||||
|
|
||||||
collection_paths = scheme_compiled_file_roots(0, NULL);
|
collection_paths = scheme_compiled_file_roots(0, NULL);
|
||||||
place_data->compiled_roots = collection_paths;
|
place_data->compiled_roots = collection_paths;
|
||||||
|
|
||||||
|
@ -451,6 +456,7 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
places_prepare_direct(place_data->current_library_collection_paths);
|
places_prepare_direct(place_data->current_library_collection_paths);
|
||||||
|
places_prepare_direct(place_data->current_library_collection_links);
|
||||||
places_prepare_direct(place_data->compiled_roots);
|
places_prepare_direct(place_data->compiled_roots);
|
||||||
places_prepare_direct(place_data->channel);
|
places_prepare_direct(place_data->channel);
|
||||||
places_prepare_direct(place_data->module);
|
places_prepare_direct(place_data->module);
|
||||||
|
@ -2633,6 +2639,8 @@ static void *place_start_proc_after_stack(void *data_arg, void *stack_base) {
|
||||||
|
|
||||||
a[0] = places_deep_direct_uncopy(place_data->current_library_collection_paths);
|
a[0] = places_deep_direct_uncopy(place_data->current_library_collection_paths);
|
||||||
scheme_current_library_collection_paths(1, a);
|
scheme_current_library_collection_paths(1, a);
|
||||||
|
a[0] = places_deep_direct_uncopy(place_data->current_library_collection_links);
|
||||||
|
scheme_current_library_collection_links(1, a);
|
||||||
a[0] = places_deep_direct_uncopy(place_data->compiled_roots);
|
a[0] = places_deep_direct_uncopy(place_data->compiled_roots);
|
||||||
scheme_compiled_file_roots(1, a);
|
scheme_compiled_file_roots(1, a);
|
||||||
scheme_seal_parameters();
|
scheme_seal_parameters();
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#define USE_COMPILED_STARTUP 1
|
#define USE_COMPILED_STARTUP 1
|
||||||
|
|
||||||
#define EXPECTED_PRIM_COUNT 1109
|
#define EXPECTED_PRIM_COUNT 1110
|
||||||
#define EXPECTED_UNSAFE_COUNT 100
|
#define EXPECTED_UNSAFE_COUNT 100
|
||||||
#define EXPECTED_FLFXNUM_COUNT 69
|
#define EXPECTED_FLFXNUM_COUNT 69
|
||||||
#define EXPECTED_EXTFL_COUNT 45
|
#define EXPECTED_EXTFL_COUNT 45
|
||||||
|
|
|
@ -4007,6 +4007,7 @@ Scheme_Object *scheme_symbol_to_string(Scheme_Object *sym);
|
||||||
#define SCHEME_SYM_WEIRDP(o) (MZ_OPT_HASH_KEY(&((Scheme_Symbol *)(o))->iso) & 0x3)
|
#define SCHEME_SYM_WEIRDP(o) (MZ_OPT_HASH_KEY(&((Scheme_Symbol *)(o))->iso) & 0x3)
|
||||||
|
|
||||||
Scheme_Object *scheme_current_library_collection_paths(int argc, Scheme_Object *argv[]);
|
Scheme_Object *scheme_current_library_collection_paths(int argc, Scheme_Object *argv[]);
|
||||||
|
Scheme_Object *scheme_current_library_collection_links(int argc, Scheme_Object *argv[]);
|
||||||
Scheme_Object *scheme_compiled_file_roots(int argc, Scheme_Object *argv[]);
|
Scheme_Object *scheme_compiled_file_roots(int argc, Scheme_Object *argv[]);
|
||||||
|
|
||||||
#ifdef MZ_USE_JIT
|
#ifdef MZ_USE_JIT
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
consistently.)
|
consistently.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MZSCHEME_VERSION "5.90.0.3"
|
#define MZSCHEME_VERSION "5.90.0.4"
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_X 5
|
#define MZSCHEME_VERSION_X 5
|
||||||
#define MZSCHEME_VERSION_Y 90
|
#define MZSCHEME_VERSION_Y 90
|
||||||
#define MZSCHEME_VERSION_Z 0
|
#define MZSCHEME_VERSION_Z 0
|
||||||
#define MZSCHEME_VERSION_W 3
|
#define MZSCHEME_VERSION_W 4
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||||
|
|
|
@ -143,6 +143,7 @@
|
||||||
" collection-path"
|
" collection-path"
|
||||||
" collection-file-path"
|
" collection-file-path"
|
||||||
" find-library-collection-paths"
|
" find-library-collection-paths"
|
||||||
|
" find-library-collection-links"
|
||||||
" path-list-string->path-list"
|
" path-list-string->path-list"
|
||||||
" find-executable-path"
|
" find-executable-path"
|
||||||
" load/use-compiled"
|
" load/use-compiled"
|
||||||
|
@ -428,9 +429,8 @@
|
||||||
"((not(car l))(append orig-l(loop(cdr l))))"
|
"((not(car l))(append orig-l(loop(cdr l))))"
|
||||||
"(else(cons(coerce-to-path(car l))(loop(cdr l))))))"
|
"(else(cons(coerce-to-path(car l))(loop(cdr l))))))"
|
||||||
" orig-l))))"
|
" orig-l))))"
|
||||||
"(define-values(all-links-paths)(find-links-path!"
|
"(define-values(find-library-collection-links)"
|
||||||
"(lambda()"
|
"(lambda()"
|
||||||
"(if(use-collection-link-paths)"
|
|
||||||
"(let*((d(find-config-dir))"
|
"(let*((d(find-config-dir))"
|
||||||
"(ht(get-config-table d))"
|
"(ht(get-config-table d))"
|
||||||
"(lf(coerce-to-path"
|
"(lf(coerce-to-path"
|
||||||
|
@ -438,21 +438,21 @@
|
||||||
"(build-path(or(hash-ref ht 'share-dir #f)"
|
"(build-path(or(hash-ref ht 'share-dir #f)"
|
||||||
" (build-path 'up \"share\"))"
|
" (build-path 'up \"share\"))"
|
||||||
" \"links.rktd\")))))"
|
" \"links.rktd\")))))"
|
||||||
"(cons(list->vector"
|
"(append"
|
||||||
|
"(list #f)"
|
||||||
|
"(if(and(use-user-specific-search-paths)"
|
||||||
|
"(use-collection-link-paths))"
|
||||||
|
"(list(build-path(find-system-path 'addon-dir)"
|
||||||
|
"(get-installation-name ht)"
|
||||||
|
" \"links.rktd\"))"
|
||||||
|
" null)"
|
||||||
|
"(if(use-collection-link-paths)"
|
||||||
"(add-config-search"
|
"(add-config-search"
|
||||||
" ht"
|
" ht"
|
||||||
" 'links-search-files"
|
" 'links-search-files"
|
||||||
"(list lf)))"
|
"(list lf))"
|
||||||
"(build-path(find-system-path 'addon-dir)"
|
" null)))))"
|
||||||
"(get-installation-name ht)"
|
"(define-values(links-cache)(make-weak-hash))"
|
||||||
" \"links.rktd\")))"
|
|
||||||
"(cons #() #f)))))"
|
|
||||||
"(define-values(links-paths)(car all-links-paths))"
|
|
||||||
"(define-values(user-links-path)(cdr all-links-paths))"
|
|
||||||
"(define-values(user-links-cache)(make-hasheq))"
|
|
||||||
"(define-values(user-links-stamp) #f)"
|
|
||||||
"(define-values(links-caches)(make-vector(vector-length links-paths)(make-hasheq)))"
|
|
||||||
"(define-values(links-stamps)(make-vector(vector-length links-paths) #f))"
|
|
||||||
"(define-values(stamp-prompt-tag)(make-continuation-prompt-tag 'stamp))"
|
"(define-values(stamp-prompt-tag)(make-continuation-prompt-tag 'stamp))"
|
||||||
"(define-values(file->stamp)"
|
"(define-values(file->stamp)"
|
||||||
"(lambda(path old-stamp)"
|
"(lambda(path old-stamp)"
|
||||||
|
@ -511,7 +511,7 @@
|
||||||
"(or(not a)"
|
"(or(not a)"
|
||||||
"(not(car a)))))"
|
"(not(car a)))))"
|
||||||
"(define-values(get-linked-collections)"
|
"(define-values(get-linked-collections)"
|
||||||
"(lambda(user? ii)"
|
"(lambda(links-path)"
|
||||||
"(call/ec(lambda(esc)"
|
"(call/ec(lambda(esc)"
|
||||||
"(define-values(make-handler)"
|
"(define-values(make-handler)"
|
||||||
"(lambda(ts)"
|
"(lambda(ts)"
|
||||||
|
@ -522,33 +522,21 @@
|
||||||
"(log-message l 'error"
|
"(log-message l 'error"
|
||||||
"(format"
|
"(format"
|
||||||
" \"error reading collection links file ~s: ~a\""
|
" \"error reading collection links file ~s: ~a\""
|
||||||
"(cond"
|
" links-path"
|
||||||
"(user? user-links-path)"
|
|
||||||
"(else(vector-ref links-paths ii)))"
|
|
||||||
"(exn-message exn))"
|
"(exn-message exn))"
|
||||||
"(current-continuation-marks))))"
|
"(current-continuation-marks))))"
|
||||||
"(void))"
|
"(void))"
|
||||||
"(when ts"
|
"(when ts"
|
||||||
"(cond"
|
"(hash-set! links-cache links-path(cons #hasheq() ts)))"
|
||||||
"(user?"
|
|
||||||
"(set! user-links-cache(make-hasheq))"
|
|
||||||
"(set! user-links-stamp ts))"
|
|
||||||
"(else"
|
|
||||||
"(vector-set! links-caches ii(make-hasheq))"
|
|
||||||
"(vector-set! links-stamps ii ts))))"
|
|
||||||
"(if(exn:fail? exn)"
|
"(if(exn:fail? exn)"
|
||||||
"(esc(make-hasheq))"
|
"(esc(make-hasheq))"
|
||||||
" exn))))"
|
" exn))))"
|
||||||
"(with-continuation-mark"
|
"(with-continuation-mark"
|
||||||
" exception-handler-key"
|
" exception-handler-key"
|
||||||
"(make-handler #f)"
|
"(make-handler #f)"
|
||||||
"(let*((a-links-path(cond"
|
"(let*((links-stamp+cache(hash-ref links-cache links-path '(#f . #hasheq())))"
|
||||||
"(user? user-links-path)"
|
"(a-links-stamp(car links-stamp+cache))"
|
||||||
"(else(vector-ref links-paths ii))))"
|
"(ts(file->stamp links-path a-links-stamp)))"
|
||||||
"(a-links-stamp(cond"
|
|
||||||
"(user? user-links-stamp)"
|
|
||||||
"(else(vector-ref links-stamps ii))))"
|
|
||||||
"(ts(file->stamp a-links-path a-links-stamp)))"
|
|
||||||
"(if(not(equal? ts a-links-stamp))"
|
"(if(not(equal? ts a-links-stamp))"
|
||||||
"(with-continuation-mark"
|
"(with-continuation-mark"
|
||||||
" exception-handler-key"
|
" exception-handler-key"
|
||||||
|
@ -557,7 +545,7 @@
|
||||||
"(lambda()"
|
"(lambda()"
|
||||||
"(let((v(if(no-file-stamp? ts)"
|
"(let((v(if(no-file-stamp? ts)"
|
||||||
" null"
|
" null"
|
||||||
"(let((p(open-input-file a-links-path 'binary)))"
|
"(let((p(open-input-file links-path 'binary)))"
|
||||||
"(dynamic-wind"
|
"(dynamic-wind"
|
||||||
" void"
|
" void"
|
||||||
"(lambda() "
|
"(lambda() "
|
||||||
|
@ -580,7 +568,7 @@
|
||||||
" v))"
|
" v))"
|
||||||
" (error \"ill-formed content\"))"
|
" (error \"ill-formed content\"))"
|
||||||
"(let((ht(make-hasheq))"
|
"(let((ht(make-hasheq))"
|
||||||
"(dir(let-values(((base name dir?)(split-path a-links-path)))"
|
"(dir(let-values(((base name dir?)(split-path links-path)))"
|
||||||
" base)))"
|
" base)))"
|
||||||
"(for-each"
|
"(for-each"
|
||||||
"(lambda(p)"
|
"(lambda(p)"
|
||||||
|
@ -611,17 +599,9 @@
|
||||||
"(hash-for-each"
|
"(hash-for-each"
|
||||||
" ht"
|
" ht"
|
||||||
"(lambda(k v)(hash-set! ht k(reverse v))))"
|
"(lambda(k v)(hash-set! ht k(reverse v))))"
|
||||||
"(cond"
|
"(hash-set! links-cache links-path(cons ts ht))"
|
||||||
"(user?"
|
|
||||||
"(set! user-links-cache ht)"
|
|
||||||
"(set! user-links-stamp ts))"
|
|
||||||
"(else"
|
|
||||||
"(vector-set! links-caches ii ht)"
|
|
||||||
"(vector-set! links-stamps ii ts)))"
|
|
||||||
" ht)))))"
|
" ht)))))"
|
||||||
"(cond"
|
"(cdr links-stamp+cache))))))))"
|
||||||
"(user? user-links-cache)"
|
|
||||||
"(else(vector-ref links-caches ii))))))))))"
|
|
||||||
"(define-values(normalize-collection-reference)"
|
"(define-values(normalize-collection-reference)"
|
||||||
"(lambda(collection collection-path)"
|
"(lambda(collection collection-path)"
|
||||||
"(cond"
|
"(cond"
|
||||||
|
@ -645,29 +625,28 @@
|
||||||
"(lambda(fail collection collection-path file-name)"
|
"(lambda(fail collection collection-path file-name)"
|
||||||
"(let-values(((collection collection-path)"
|
"(let-values(((collection collection-path)"
|
||||||
"(normalize-collection-reference collection collection-path)))"
|
"(normalize-collection-reference collection collection-path)))"
|
||||||
"(let((all-paths(let((sym(string->symbol(if(path? collection)"
|
"(let((all-paths(let((sym(string->symbol "
|
||||||
|
"(if(path? collection)"
|
||||||
"(path->string collection)"
|
"(path->string collection)"
|
||||||
" collection)))"
|
" collection))))"
|
||||||
"(links?(use-collection-link-paths)))"
|
"(let loop((l(current-library-collection-links)))"
|
||||||
|
"(cond"
|
||||||
|
"((null? l) null)"
|
||||||
|
"((not(car l))"
|
||||||
|
"(append "
|
||||||
|
"(current-library-collection-paths)"
|
||||||
|
"(loop(cdr l))))"
|
||||||
|
"((hash?(car l))"
|
||||||
"(append"
|
"(append"
|
||||||
"(if(and links? "
|
"(map box(hash-ref(car l) sym null))"
|
||||||
"(use-user-specific-search-paths)"
|
"(hash-ref(car l) #f null)"
|
||||||
" user-links-path)"
|
"(loop(cdr l))))"
|
||||||
"(append"
|
"(else"
|
||||||
"(let((ht(get-linked-collections #t 0)))"
|
"(let((ht(get-linked-collections(car l))))"
|
||||||
"(append(hash-ref ht sym null)"
|
"(append "
|
||||||
"(hash-ref ht #f null))))"
|
"(hash-ref ht sym null)"
|
||||||
" null)"
|
|
||||||
"(if links?"
|
|
||||||
"(let loop((ii 0))"
|
|
||||||
"(if(ii . >= .(vector-length links-paths))"
|
|
||||||
" null"
|
|
||||||
"(let((ht(get-linked-collections #f ii)))"
|
|
||||||
"(append(hash-ref ht sym null)"
|
|
||||||
"(hash-ref ht #f null)"
|
"(hash-ref ht #f null)"
|
||||||
"(loop(add1 ii))))))"
|
"(loop(cdr l))))))))))"
|
||||||
" null)"
|
|
||||||
"(current-library-collection-paths)))))"
|
|
||||||
"(define-values(done)"
|
"(define-values(done)"
|
||||||
"(lambda(p)"
|
"(lambda(p)"
|
||||||
"(if file-name(build-path p file-name) p)))"
|
"(if file-name(build-path p file-name) p)))"
|
||||||
|
|
|
@ -190,6 +190,7 @@
|
||||||
collection-path
|
collection-path
|
||||||
collection-file-path
|
collection-file-path
|
||||||
find-library-collection-paths
|
find-library-collection-paths
|
||||||
|
find-library-collection-links
|
||||||
path-list-string->path-list
|
path-list-string->path-list
|
||||||
find-executable-path
|
find-executable-path
|
||||||
load/use-compiled
|
load/use-compiled
|
||||||
|
@ -504,16 +505,8 @@
|
||||||
[else (cons (coerce-to-path (car l)) (loop (cdr l)))]))
|
[else (cons (coerce-to-path (car l)) (loop (cdr l)))]))
|
||||||
orig-l))))
|
orig-l))))
|
||||||
|
|
||||||
(define-values (all-links-paths) (find-links-path!
|
(define-values (find-library-collection-links)
|
||||||
;; This thunk is called once per place, and the result
|
|
||||||
;; is remembered for later invocations. Otherwise, the
|
|
||||||
;; search for the config file can trip over filesystem
|
|
||||||
;; restrictions imposed by security guards.
|
|
||||||
(lambda ()
|
(lambda ()
|
||||||
;; If `use-collection-link-paths' is disabled on
|
|
||||||
;; startup, then don't try to read the configuration
|
|
||||||
;; file, either.
|
|
||||||
(if (use-collection-link-paths)
|
|
||||||
(let* ([d (find-config-dir)]
|
(let* ([d (find-config-dir)]
|
||||||
[ht (get-config-table d)]
|
[ht (get-config-table d)]
|
||||||
[lf (coerce-to-path
|
[lf (coerce-to-path
|
||||||
|
@ -521,25 +514,28 @@
|
||||||
(build-path (or (hash-ref ht 'share-dir #f)
|
(build-path (or (hash-ref ht 'share-dir #f)
|
||||||
(build-path 'up "share"))
|
(build-path 'up "share"))
|
||||||
"links.rktd")))])
|
"links.rktd")))])
|
||||||
(cons (list->vector
|
(append
|
||||||
|
;; `#f' means `current-library-collection-paths':
|
||||||
|
(list #f)
|
||||||
|
;; user-specific
|
||||||
|
(if (and (use-user-specific-search-paths)
|
||||||
|
(use-collection-link-paths))
|
||||||
|
(list (build-path (find-system-path 'addon-dir)
|
||||||
|
(get-installation-name ht)
|
||||||
|
"links.rktd"))
|
||||||
|
null)
|
||||||
|
;; installation-wide:
|
||||||
|
(if (use-collection-link-paths)
|
||||||
(add-config-search
|
(add-config-search
|
||||||
ht
|
ht
|
||||||
'links-search-files
|
'links-search-files
|
||||||
(list lf)))
|
(list lf))
|
||||||
(build-path (find-system-path 'addon-dir)
|
null)))))
|
||||||
(get-installation-name ht)
|
|
||||||
"links.rktd")))
|
|
||||||
(cons #() #f)))))
|
|
||||||
|
|
||||||
(define-values (links-paths) (car all-links-paths))
|
;; map from link-file names to cached information:
|
||||||
(define-values (user-links-path) (cdr all-links-paths))
|
(define-values (links-cache) (make-weak-hash))
|
||||||
|
|
||||||
(define-values (user-links-cache) (make-hasheq))
|
|
||||||
(define-values (user-links-stamp) #f)
|
|
||||||
|
|
||||||
(define-values (links-caches) (make-vector (vector-length links-paths) (make-hasheq)))
|
|
||||||
(define-values (links-stamps) (make-vector (vector-length links-paths) #f))
|
|
||||||
|
|
||||||
|
;; used for low-level except abort below:
|
||||||
(define-values (stamp-prompt-tag) (make-continuation-prompt-tag 'stamp))
|
(define-values (stamp-prompt-tag) (make-continuation-prompt-tag 'stamp))
|
||||||
|
|
||||||
(define-values (file->stamp)
|
(define-values (file->stamp)
|
||||||
|
@ -606,7 +602,9 @@
|
||||||
(not (car a)))))
|
(not (car a)))))
|
||||||
|
|
||||||
(define-values (get-linked-collections)
|
(define-values (get-linked-collections)
|
||||||
(lambda (user? ii)
|
(lambda (links-path)
|
||||||
|
;; Use/save information in `links-cache', relying on filesystem-change events
|
||||||
|
;; or a copy of the file to detect when the cache is stale.
|
||||||
(call/ec (lambda (esc)
|
(call/ec (lambda (esc)
|
||||||
(define-values (make-handler)
|
(define-values (make-handler)
|
||||||
(lambda (ts)
|
(lambda (ts)
|
||||||
|
@ -617,20 +615,12 @@
|
||||||
(log-message l 'error
|
(log-message l 'error
|
||||||
(format
|
(format
|
||||||
"error reading collection links file ~s: ~a"
|
"error reading collection links file ~s: ~a"
|
||||||
(cond
|
links-path
|
||||||
[user? user-links-path]
|
|
||||||
[else (vector-ref links-paths ii)])
|
|
||||||
(exn-message exn))
|
(exn-message exn))
|
||||||
(current-continuation-marks))))
|
(current-continuation-marks))))
|
||||||
(void))
|
(void))
|
||||||
(when ts
|
(when ts
|
||||||
(cond
|
(hash-set! links-cache links-path (cons #hasheq() ts)))
|
||||||
[user?
|
|
||||||
(set! user-links-cache (make-hasheq))
|
|
||||||
(set! user-links-stamp ts)]
|
|
||||||
[else
|
|
||||||
(vector-set! links-caches ii (make-hasheq))
|
|
||||||
(vector-set! links-stamps ii ts)]))
|
|
||||||
(if (exn:fail? exn)
|
(if (exn:fail? exn)
|
||||||
(esc (make-hasheq))
|
(esc (make-hasheq))
|
||||||
;; re-raise the exception (which is probably a break)
|
;; re-raise the exception (which is probably a break)
|
||||||
|
@ -638,13 +628,9 @@
|
||||||
(with-continuation-mark
|
(with-continuation-mark
|
||||||
exception-handler-key
|
exception-handler-key
|
||||||
(make-handler #f)
|
(make-handler #f)
|
||||||
(let* ([a-links-path (cond
|
(let* ([links-stamp+cache (hash-ref links-cache links-path '(#f . #hasheq()))]
|
||||||
[user? user-links-path]
|
[a-links-stamp (car links-stamp+cache)]
|
||||||
[else (vector-ref links-paths ii)])]
|
[ts (file->stamp links-path a-links-stamp)])
|
||||||
[a-links-stamp (cond
|
|
||||||
[user? user-links-stamp]
|
|
||||||
[else (vector-ref links-stamps ii)])]
|
|
||||||
[ts (file->stamp a-links-path a-links-stamp)])
|
|
||||||
(if (not (equal? ts a-links-stamp))
|
(if (not (equal? ts a-links-stamp))
|
||||||
(with-continuation-mark
|
(with-continuation-mark
|
||||||
exception-handler-key
|
exception-handler-key
|
||||||
|
@ -653,7 +639,7 @@
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ([v (if (no-file-stamp? ts)
|
(let ([v (if (no-file-stamp? ts)
|
||||||
null
|
null
|
||||||
(let ([p (open-input-file a-links-path 'binary)])
|
(let ([p (open-input-file links-path 'binary)])
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
void
|
void
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
@ -676,7 +662,7 @@
|
||||||
v))
|
v))
|
||||||
(error "ill-formed content"))
|
(error "ill-formed content"))
|
||||||
(let ([ht (make-hasheq)]
|
(let ([ht (make-hasheq)]
|
||||||
[dir (let-values ([(base name dir?) (split-path a-links-path)])
|
[dir (let-values ([(base name dir?) (split-path links-path)])
|
||||||
base)])
|
base)])
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (p)
|
(lambda (p)
|
||||||
|
@ -715,17 +701,9 @@
|
||||||
ht
|
ht
|
||||||
(lambda (k v) (hash-set! ht k (reverse v))))
|
(lambda (k v) (hash-set! ht k (reverse v))))
|
||||||
;; save table & file content:
|
;; save table & file content:
|
||||||
(cond
|
(hash-set! links-cache links-path (cons ts ht))
|
||||||
[user?
|
|
||||||
(set! user-links-cache ht)
|
|
||||||
(set! user-links-stamp ts)]
|
|
||||||
[else
|
|
||||||
(vector-set! links-caches ii ht)
|
|
||||||
(vector-set! links-stamps ii ts)])
|
|
||||||
ht)))))
|
ht)))))
|
||||||
(cond
|
(cdr links-stamp+cache))))))))
|
||||||
[user? user-links-cache]
|
|
||||||
[else (vector-ref links-caches ii)]))))))))
|
|
||||||
|
|
||||||
(define-values (normalize-collection-reference)
|
(define-values (normalize-collection-reference)
|
||||||
(lambda (collection collection-path)
|
(lambda (collection collection-path)
|
||||||
|
@ -752,32 +730,38 @@
|
||||||
(lambda (fail collection collection-path file-name)
|
(lambda (fail collection collection-path file-name)
|
||||||
(let-values ([(collection collection-path)
|
(let-values ([(collection collection-path)
|
||||||
(normalize-collection-reference collection collection-path)])
|
(normalize-collection-reference collection collection-path)])
|
||||||
(let ([all-paths (let ([sym (string->symbol (if (path? collection)
|
(let ([all-paths (let ([sym (string->symbol
|
||||||
|
(if (path? collection)
|
||||||
(path->string collection)
|
(path->string collection)
|
||||||
collection))]
|
collection))])
|
||||||
[links? (use-collection-link-paths)])
|
(let loop ([l (current-library-collection-links)])
|
||||||
|
(cond
|
||||||
|
[(null? l) null]
|
||||||
|
[(not (car l))
|
||||||
|
;; #f is the point where we try the old parameter:
|
||||||
(append
|
(append
|
||||||
;; list of paths and (box path)s:
|
(current-library-collection-paths)
|
||||||
(if (and links?
|
(loop (cdr l)))]
|
||||||
(use-user-specific-search-paths)
|
[(hash? (car l))
|
||||||
user-links-path)
|
;; A hash table maps a collection-name symbol
|
||||||
|
;; to a list of paths. We need to wrap each path
|
||||||
|
;; in a box, because that's how the code below
|
||||||
|
;; knows that it's a single collection's directory.
|
||||||
|
;; A hash table can also map #f to a list of paths
|
||||||
|
;; for directories that hold collections.
|
||||||
(append
|
(append
|
||||||
(let ([ht (get-linked-collections #t 0)])
|
(map box (hash-ref (car l) sym null))
|
||||||
(append (hash-ref ht sym null)
|
(hash-ref (car l) #f null)
|
||||||
(hash-ref ht #f null))))
|
(loop (cdr l)))]
|
||||||
null)
|
[else
|
||||||
;; list of paths and (box path)s:
|
(let ([ht (get-linked-collections (car l))])
|
||||||
(if links?
|
(append
|
||||||
(let loop ([ii 0])
|
;; Table values are lists of paths and (box path)s,
|
||||||
(if (ii . >= . (vector-length links-paths))
|
;; where a (box path) is a collection directory
|
||||||
null
|
;; (instead of a directory containing collections).
|
||||||
(let ([ht (get-linked-collections #f ii)])
|
(hash-ref ht sym null)
|
||||||
(append (hash-ref ht sym null)
|
|
||||||
(hash-ref ht #f null)
|
(hash-ref ht #f null)
|
||||||
(loop (add1 ii))))))
|
(loop (cdr l))))])))])
|
||||||
null)
|
|
||||||
;; list of paths:
|
|
||||||
(current-library-collection-paths)))])
|
|
||||||
(define-values (done)
|
(define-values (done)
|
||||||
(lambda (p)
|
(lambda (p)
|
||||||
(if file-name (build-path p file-name) p)))
|
(if file-name (build-path p file-name) p)))
|
||||||
|
|
|
@ -669,7 +669,6 @@ void scheme_init_paramz(Scheme_Env *env)
|
||||||
GLOBAL_PRIM_W_ARITY("check-for-break" , check_break_now , 0, 0, newenv);
|
GLOBAL_PRIM_W_ARITY("check-for-break" , check_break_now , 0, 0, newenv);
|
||||||
GLOBAL_PRIM_W_ARITY("reparameterize" , reparameterize , 1, 1, newenv);
|
GLOBAL_PRIM_W_ARITY("reparameterize" , reparameterize , 1, 1, newenv);
|
||||||
GLOBAL_PRIM_W_ARITY("make-custodian-from-main", make_custodian_from_main, 0, 0, newenv);
|
GLOBAL_PRIM_W_ARITY("make-custodian-from-main", make_custodian_from_main, 0, 0, newenv);
|
||||||
GLOBAL_PRIM_W_ARITY("find-links-path!" , scheme_find_links_path , 1, 1, newenv);
|
|
||||||
|
|
||||||
scheme_finish_primitive_module(newenv);
|
scheme_finish_primitive_module(newenv);
|
||||||
scheme_protect_primitive_provide(newenv, NULL);
|
scheme_protect_primitive_provide(newenv, NULL);
|
||||||
|
@ -7454,6 +7453,7 @@ static void make_initial_config(Scheme_Thread *p)
|
||||||
: scheme_false));
|
: scheme_false));
|
||||||
|
|
||||||
init_param(cells, paramz, MZCONFIG_COLLECTION_PATHS, scheme_null);
|
init_param(cells, paramz, MZCONFIG_COLLECTION_PATHS, scheme_null);
|
||||||
|
init_param(cells, paramz, MZCONFIG_COLLECTION_LINKS, scheme_null);
|
||||||
|
|
||||||
{
|
{
|
||||||
Scheme_Security_Guard *sg;
|
Scheme_Security_Guard *sg;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user