diff --git a/.merlin b/.merlin
index 33392d20..d5a2d81a 100644
--- a/.merlin
+++ b/.merlin
@@ -1,20 +1,37 @@
-S core
-S misc
-S string
-S pervasives
-S tests
-S examples
+S src/core
+S src/data/
+S src/io
+S src/iter/
+S src/advanced/
+S src/lwt/
+S src/sexp/
+S src/threads/
+S src/misc
+S src/string
+S src/bigarray
+S src/pervasives
S benchs
-B _build/core
-B _build/misc
-B _build/string
-B _build/pervasives
-B _build/tests
+S examples
+S tests
+B _build/src/core
+B _build/src/data/
+B _build/src/io
+B _build/src/iter/
+B _build/src/advanced/
+B _build/src/lwt/
+B _build/src/sexp/
+B _build/src/threads/
+B _build/src/misc
+B _build/src/string
+B _build/src/bigarray
+B _build/src/pervasives
+B _build/benchs
B _build/examples
-B _build/benchs/
+B _build/tests
PKG oUnit
PKG benchmark
PKG threads
PKG threads.posix
PKG lwt
+PKG bigarray
FLG -w +a -w -4 -w -44
diff --git a/.ocamlinit b/.ocamlinit
index 4bc62be7..2d7217dd 100644
--- a/.ocamlinit
+++ b/.ocamlinit
@@ -1,24 +1,29 @@
#use "topfind";;
#thread
-#directory "_build/core";;
-#directory "_build/misc";;
-#directory "_build/pervasives/";;
-#directory "_build/string";;
-#directory "_build/threads";;
+#require "bigarray";;
+#directory "_build/src/core";;
+#directory "_build/src/misc";;
+#directory "_build/src/pervasives/";;
+#directory "_build/src/string";;
+#directory "_build/src/io";;
+#directory "_build/src/iter";;
+#directory "_build/src/data";;
+#directory "_build/src/sexp";;
+#directory "_build/src/bigarray/";;
+#directory "_build/src/threads";;
#directory "_build/tests/";;
#load "containers.cma";;
+#load "containers_iter.cma";;
+#load "containers_data.cma";;
+#load "containers_io.cma";;
+#load "containers_sexp.cma";;
#load "containers_string.cma";;
#load "containers_pervasives.cma";;
+#load "containers_bigarray.cma";;
#load "containers_misc.cma";;
#thread;;
#load "containers_thread.cma";;
open Containers_misc;;
-#install_printer Sexp.print;;
-#install_printer Bencode.pretty;;
-#install_printer HGraph.Default.fmt;;
-#require "CamlGI";;
-#load "containers_cgi.cma";;
-let pp_html fmt h = Format.pp_print_string fmt (ToWeb.HTML.render h);;
-#install_printer pp_html;;
+#install_printer CCSexp.print;;
(* vim:syntax=ocaml:
*)
diff --git a/AUTHORS.md b/AUTHORS.md
index 3c8c8d77..39b3731c 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -7,3 +7,4 @@
- Whitequark (Peter Zotov)
- hcarty (Hezekiah M. Carty)
- struktured (Carmelo Piccione)
+- Bernardo da Costa
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f931d873..22355ab8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
# Changelog
+## 0.7
+
+### breaking
+
+- remove `cgi`/
+- removed useless Lwt-related module
+- remove `CCGen` and `CCsequence` (use the separate libraries)
+- split the library into smaller pieces (with `containers.io`, `containers.iter`,
+ `containers.sexp`, `containers.data`)
+
+#### other changes
+
+- cleanup: move sub-libraries to their own subdir each; mv everything into `src/`
+- `sexp`:
+ * `CCSexp` now splitted into `CCSexp` (manipulating expressions) and `CCSexpStream`
+ * add `CCSexpM` for a simpler, monadic parser of S-expressions (deprecating `CCSexpStream`)
+- `core`:
+ * `CCString.fold`
+ * `CCstring.suffix`
+ * more efficient `CCString.init`
+ * fix errors in documentation of `CCString` (slightly over-reaching sed)
+ * add `CCFloat.{fsign, sign_exn}` (thanks @bernardofpc)
+- new `containers.bigarray`, with `CCBigstring`
+- `CCHashtbl.map_list`
+- `io`:
+ * `CCIO.read_all` now with ?size parameter
+ * use `Bytes.extend` (praise modernity!)
+ * bugfix in `CCIO.read_all` and `CCIO.read_chunks`
+- use `-no-alias-deps`
+
## 0.6.1
- use subtree `gen/` for `CCGen` (symlink) rather than a copy.
diff --git a/Makefile b/Makefile
index 7f42347e..3796bae5 100644
--- a/Makefile
+++ b/Makefile
@@ -54,12 +54,24 @@ push_doc: doc
scp -r containers_misc.docdir/* cedeela.fr:~/simon/root/software/containers/misc/
scp -r containers_lwt.docdir/* cedeela.fr:~/simon/root/software/containers/lwt/
-DONTTEST=myocamlbuild.ml setup.ml $(wildcard **/*.cppo*)
+DONTTEST=myocamlbuild.ml setup.ml $(wildcard src/**/*.cppo.*)
QTESTABLE=$(filter-out $(DONTTEST), \
- $(wildcard core/*.ml) $(wildcard core/*.mli) \
- $(wildcard core/*.cppo.ml) $(wildcard core/*.cppo.mli) \
- $(wildcard misc/*.ml) $(wildcard misc/*.mli) \
- $(wildcard string/*.ml) $(wildcard string/*.mli) \
+ $(wildcard src/core/*.ml) \
+ $(wildcard src/core/*.mli) \
+ $(wildcard src/data/*.ml) \
+ $(wildcard src/data/*.mli) \
+ $(wildcard src/string/*.ml) \
+ $(wildcard src/string/*.mli) \
+ $(wildcard src/io/*.ml) \
+ $(wildcard src/io/*.mli) \
+ $(wildcard src/sexp/*.ml) \
+ $(wildcard src/sexp/*.mli) \
+ $(wildcard src/advanced/*.ml) \
+ $(wildcard src/advanced/*.mli) \
+ $(wildcard src/iter/*.ml) \
+ $(wildcard src/iter/*.mli) \
+ $(wildcard src/bigarray/*.ml) \
+ $(wildcard src/bigarray/*.mli) \
)
qtest-clean:
@@ -78,11 +90,11 @@ QTEST_PREAMBLE='open CCFun;; '
qtest-gen: qtest-clean
@mkdir -p qtest
- @if which qtest ; then \
+ @if which qtest > /dev/null ; then \
qtest extract --preamble $(QTEST_PREAMBLE) \
- -o qtest/run_qtest.cppo.ml \
+ -o qtest/run_qtest.ml \
$(QTESTABLE) 2> /dev/null ; \
- else touch qtest/run_qtest.cppo.ml ; \
+ else touch qtest/run_qtest.ml ; \
fi
push-stable:
@@ -109,11 +121,10 @@ VERSION=$(shell awk '/^Version:/ {print $$2}' _oasis)
update_next_tag:
@echo "update version to $(VERSION)..."
- sed -i "s/NEXT_VERSION/$(VERSION)/g" **/*.ml **/*.mli
- sed -i "s/NEXT_RELEASE/$(VERSION)/g" **/*.ml **/*.mli
+ zsh -c 'sed -i "s/NEXT_VERSION/$(VERSION)/g" **/*.ml **/*.mli'
+ zsh -c 'sed -i "s/NEXT_RELEASE/$(VERSION)/g" **/*.ml **/*.mli'
udpate_sequence:
git subtree pull --prefix sequence sequence stable --squash
.PHONY: examples push_doc tags qtest clean update_sequence update_next_tag push-stable clean-generated
-
diff --git a/README.md b/README.md
index bdd26862..71e8ecde 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,37 @@
ocaml-containers
================
-1. A usable, reasonably well-designed library that extends OCaml's standard
- library (in `core/`, packaged under `containers` in ocamlfind. Modules
- are totally independent and are prefixed with `CC` (for "containers-core"
- or "companion-cube" because I'm megalomaniac). This part should be
- usable and should work. For instance, `CCList` contains functions and
- lists including safe versions of `map` and `append`.
-2. A satellite library, `containers.string` (in directory `string`) with
+
+
+What is _containers_?
+
+- A usable, reasonably well-designed library that extends OCaml's standard
+ library (in `core/`, packaged under `containers` in ocamlfind. Modules
+ are totally independent and are prefixed with `CC` (for "containers-core"
+ or "companion-cube" because I'm megalomaniac). This part should be
+ usable and should work. For instance, `CCList` contains functions and
+ lists including safe versions of `map` and `append`.
+- Several small additional libraries that complement it:
+ * `containers.data` with additional data structures that don't have an
+ equivalent in the standard library;
+ * `containers.io` with utils to handle files and I/O streams;
+ * `containers.iter` with list-like and tree-like iterators;
+ * `containers.string` (in directory `string`) with
a few packed modules that deal with strings (Levenshtein distance,
KMP search algorithm, and a few naive utils). Again, modules are independent
and sometimes parametric on the string and char types (so they should
be able to deal with your favorite unicode library).
-3. A drop-in replacement to the standard library, `containers.pervasives`,
- that defined a `CCPervasives` module intented to be opened to extend some
- modules of the stdlib.
-4. A sub-library with complicated abstractions, `containers.advanced` (with
- a LINQ-like query module, batch operations using GADTs, and others)
-5. A library using [Lwt](https://github.com/ocsigen/lwt/), `containers.lwt`.
- Currently only contains experimental, unstable stuff.
-6. Random stuff, with *NO* *GUARANTEE* of even being barely usable or tested,
- in other dirs (mostly `misc` but also `lwt` and `threads`). It's where I
- tend to write code when I want to test some idea, so half the modules (at
- least) are unfinished or don't really work.
+- A drop-in replacement to the standard library, `containers.pervasives`,
+ that defined a `CCPervasives` module intented to be opened to extend some
+ modules of the stdlib.
+- A sub-library with complicated abstractions, `containers.advanced` (with
+ a LINQ-like query module, batch operations using GADTs, and others).
+- A library using [Lwt](https://github.com/ocsigen/lwt/), `containers.lwt`.
+ Currently only contains experimental, unstable stuff.
+- Random stuff, with *NO* *GUARANTEE* of even being barely usable or tested,
+ in other dirs (mostly `misc` but also `lwt` and `threads`). It's where I
+ tend to write code when I want to test some idea, so half the modules (at
+ least) are unfinished or don't really work.
Some of the modules have been moved to their own repository (e.g. `sequence`,
`gen`, `qcheck`) and are on opam for great fun and profit.
@@ -52,12 +61,15 @@ If you have comments, requests, or bugfixes, please share them! :-)
This code is free, under the BSD license.
+The logo (`media/logo.png`) is
+CC-SA3 [wikimedia](http://en.wikipedia.org/wiki/File:Hypercube.svg).
+
## Contents
The design is mostly centered around polymorphism rather than functors. Such
structures comprise (some modules in `misc/`, some other in `core/`):
-### Core Structures
+### Core Modules (extension of the standard library)
the core library, `containers`, now depends on
[cppo](https://github.com/mjambon/cppo) and `base-bytes` (provided
@@ -65,36 +77,50 @@ by ocamlfind).
Documentation [here](http://cedeela.fr/~simon/software/containers).
-- `CCHeap`, a purely functional heap structure.
+- `CCHeap`, a purely functional heap structure
+- `CCVector`, a growable array (pure OCaml, no C) with mutability annotations
+- `CCList`, functions on lists, including tail-recursive implementations of `map` and `append` and many other things
+- `CCArray`, utilities on arrays and slices
+- `CCHashtbl`, `CCMap` extensions of the standard modules `Hashtbl` and `Map`
+- `CCInt`
+- `CCString` (basic string operations)
+- `CCPair` (cartesian products)
+- `CCOpt` (options, very useful)
+- `CCFun` (function combinators)
+- `CCBool`
+- `CCFloat`
+- `CCOrd` (combinators for total orderings)
+- `CCRandom` (combinators for random generators)
+- `CCPrint` (printing combinators)
+- `CCHash` (hashing combinators)
+- `CCError` (monadic error handling, very useful)
+
+### Containers.data
+
+- `CCCache`, memoization caches, LRU, etc.
+- `CCFlatHashtbl`, a flat (open-addressing) hashtable functorial implementation
+- `CCTrie`, a prefix tree
+- `CCMultimap` and `CCMultiset`, functors defining persistent structures
- `CCFQueue`, a purely functional double-ended queue structure
- `CCBV`, mutable bitvectors
- `CCPersistentHashtbl`, a semi-persistent hashtable (similar to [persistent arrays](https://www.lri.fr/~filliatr/ftp/ocaml/ds/parray.ml.html))
-- `CCVector`, a growable array (pure OCaml, no C) with mutability annotations
-- `CCGen` and `CCSequence`, generic iterators structures (with structural types so they can be defined in several places). They are also available in their own repository and opam packages (`gen` and `sequence`). Note that the `@since` annotations may not be accurate because of the use of `git subtree`.
-- `CCKList`, a persistent iterator structure (akin to a lazy list)
-- `CCList`, functions on lists, including tail-recursive implementations of `map` and `append` and many other things
-- `CCArray`, utilities on arrays and slices
-- `CCMultimap` and `CCMultiset`, functors defining persistent structures
-- `CCHashtbl`, `CCMap` extensions of the standard modules `Hashtbl` and `Map`
-- `CCFlatHashtbl`, a flat (open-addressing) hashtable functorial implementation
-- `CCKTree`, an abstract lazy tree structure (similar to what `CCKlist` is to lists)
-- `CCTrie`, a prefix tree
-- small modules (basic types, utilities):
- - `CCInt`
- - `CCString` (basic string operations)
- - `CCPair` (cartesian products)
- - `CCOpt` (options, very useful)
- - `CCFun` (function combinators)
- - `CCBool`
- - `CCFloat`
- - `CCOrd` (combinators for total orderings)
- - `CCRandom` (combinators for random generators)
- - `CCPrint` (printing combinators)
- - `CCHash` (hashing combinators)
- - `CCError` (monadic error handling, very useful)
-- `CCSexp`, a small S-expression library
+
+### Containers.io
+
- `CCIO`, basic utilities for IO
-- `CCCache`, memoization caches, LRU, etc.
+
+### Containers.sexp
+
+A small S-expression library.
+
+- `CCSexp`, a small S-expression library
+
+### Containers.iter
+
+Iterators:
+
+- `CCKList`, a persistent iterator structure (akin to a lazy list, without memoization)
+- `CCKTree`, an abstract lazy tree structure
### String
@@ -136,19 +162,14 @@ access to elements by their index.
- `Univ`, a universal type encoding with affectation
- `FlatHashtbl`, a (deprecated) open addressing hashtable with
a functorial interface (replaced by PHashtbl)
-- `UnionFind`, a functorial imperative Union-Find structure.
+- `UnionFind`, a functorial imperative Union-Find structure
### Others
- `Future`, a set of tools for preemptive threading, including a thread pool,
monadic futures, and MVars (concurrent boxes)
-Some serialisation formats are also implemented, with a streaming, non-blocking
-interface that allows the user to feed the input in chunk by chunk (useful
-in combination with Lwt/Async). Currently, the modules are:
-
-- `Bencode`, for the [B-encode format](http://en.wikipedia.org/wiki/Bencode),
-- `Sexp`, for S-expressions.
+- `containers.lwt` contains [Lwt](http://ocsigen.org/lwt/)-related modules (experimental)
There is a QuickCheck-like library called `QCheck` (now in its own repo).
@@ -175,3 +196,18 @@ To build the small benchmarking suite (requires `benchmark`):
$ opam install benchmark
$ make bench
$ ./benchs.native
+
+## Contributing
+
+PRs on github are welcome (patches by email too, if you prefer so).
+
+A few guidelines:
+
+- no dependencies between basic modules (even just for signatures);
+- add `@since` tags for new functions;
+- add tests if possible (using `qtest`).
+
+Powered by
+
+
diff --git a/_oasis b/_oasis
index 267dc2e2..ab2a2d77 100644
--- a/_oasis
+++ b/_oasis
@@ -1,6 +1,6 @@
OASISFormat: 0.4
Name: containers
-Version: 0.6.1
+Version: 0.7
Homepage: https://github.com/c-cube/ocaml-containers
Authors: Simon Cruanes
License: BSD-2-clause
@@ -8,6 +8,7 @@ LicenseFile: LICENSE
Plugins: META (0.3), DevFiles (0.3)
OCamlVersion: >= 4.00.1
BuildTools: ocamlbuild
+AlphaFeatures: ocamlbuild_more_args
Synopsis: A modular standard library focused on data structures.
Description:
@@ -24,10 +25,6 @@ Flag "misc"
Description: Build the misc library, containing everything from the rotating kitchen sink to automatic banana distributors
Default: false
-Flag "cgi"
- Description: Build modules related to FastCGI, depending on CamlGI
- Default: false
-
Flag "lwt"
Description: Build modules which depend on Lwt
Default: false
@@ -40,80 +37,105 @@ Flag "bench"
Description: Build and run benchmarks
Default: false
+Flag "bigarray"
+ Description: Build modules that depend on bigarrays
+ Default: false
+
Library "containers"
- Path: core
- Modules: CCVector, CCDeque, CCGen, Gen_intf, CCSequence, CCFQueue, CCMultiMap,
- CCMultiSet, CCBV, CCPrint, CCPersistentHashtbl, CCError,
- CCHeap, CCList, CCOpt, CCPair, CCFun, CCHash,
- CCKList, CCInt, CCBool, CCFloat, CCArray, CCOrd, CCIO,
- CCRandom, CCKTree, CCTrie, CCString, CCHashtbl,
- CCFlatHashtbl, CCSexp, CCMap, CCCache
+ Path: src/core
+ Modules: CCVector, CCPrint, CCError, CCHeap, CCList, CCOpt, CCPair,
+ CCFun, CCHash, CCInt, CCBool, CCFloat, CCArray,
+ CCOrd, CCRandom, CCString, CCHashtbl, CCMap
BuildDepends: bytes
+Library "containers_io"
+ Path: src/io
+ Modules: CCIO
+ BuildDepends: bytes
+ FindlibParent: containers
+ FindlibName: io
+
+Library "containers_sexp"
+ Path: src/sexp
+ Modules: CCSexp, CCSexpStream, CCSexpM
+ BuildDepends: bytes
+ FindlibParent: containers
+ FindlibName: sexp
+
+Library "containers_data"
+ Path: src/data
+ Modules: CCMultiMap, CCMultiSet, CCTrie, CCFlatHashtbl, CCCache,
+ CCPersistentHashtbl, CCDeque, CCFQueue, CCBV, CCMixtbl
+ FindlibParent: containers
+ FindlibName: data
+
+Library "containers_iter"
+ Path: src/iter
+ Modules: CCKTree, CCKList
+ FindlibParent: containers
+ FindlibName: iter
+
Library "containers_string"
- Path: string
+ Path: src/string
Pack: true
Modules: KMP, Levenshtein
FindlibName: string
FindlibParent: containers
Library "containers_advanced"
- Path: advanced
+ Path: src/advanced
Pack: true
Modules: CCLinq, CCBatch, CCCat, CCMonadIO
FindlibName: advanced
FindlibParent: containers
- BuildDepends: containers
+ BuildDepends: containers, sequence
+
+Library "containers_bigarray"
+ Path: src/bigarray
+ Modules: CCBigstring
+ FindlibName: bigarray
+ FindlibParent: containers
+ BuildDepends: containers, bigarray, bytes
Library "containers_pervasives"
- Path: pervasives
+ Path: src/pervasives
Modules: CCPervasives
BuildDepends: containers
FindlibName: pervasives
FindlibParent: containers
Library "containers_misc"
- Path: misc
+ Path: src/misc
Pack: true
Modules: FHashtbl, FlatHashtbl, Hashset,
Heap, LazyGraph, PersistentGraph,
PHashtbl, SkipList, SplayTree, SplayMap, Univ,
Bij, PiCalculus, RAL, UnionFind, SmallSet, AbsSet, CSM,
TTree, PrintBox, HGraph, Automaton, Conv, Bidir, Iteratee,
- BTree, Ty, Cause, AVL, ParseReact, Mixtbl
- BuildDepends: unix,containers
+ BTree, Ty, Cause, AVL, ParseReact
+ BuildDepends: containers, containers.data
FindlibName: misc
FindlibParent: containers
Library "containers_thread"
- Path: threads/
+ Path: src/threads/
Modules: CCFuture
FindlibName: thread
FindlibParent: containers
Build$: flag(thread)
Install$: flag(thread)
- BuildDepends: containers,threads
- XMETARequires: containers,threads
+ BuildDepends: containers, threads
+ XMETARequires: containers, threads
Library "containers_lwt"
- Path: lwt
- Modules: Behavior, Lwt_automaton, Lwt_actor
+ Path: src/lwt
+ Modules: Lwt_automaton, Lwt_actor
Pack: true
FindlibName: lwt
FindlibParent: containers
Build$: flag(lwt) && flag(misc)
Install$: flag(lwt) && flag(misc)
- BuildDepends: containers, lwt, lwt.unix, containers.misc
-
-Library "containers_cgi"
- Path: cgi
- Modules: ToWeb
- FindlibName: cgi
- FindlibParent: containers
- Build$: flag(cgi)
- Install$: flag(cgi)
- BuildDepends: containers,CamlGI
- XMETARequires: containers,CamlGI
+ BuildDepends: containers, lwt, containers.misc
Document containers
Title: Containers docs
@@ -121,39 +143,13 @@ Document containers
BuildTools+: ocamldoc
Install: true
XOCamlbuildPath: .
- XOCamlbuildLibraries: containers,containers.string
-
-Document containers_misc
- Title: Containers_misc docs
- Type: ocamlbuild (0.3)
- BuildTools+: ocamldoc
- Install: true
- XOCamlbuildPath: .
- XOCamlbuildLibraries: containers.misc
-
-Document containers_string
- Title: Containers_string docs
- Type: ocamlbuild (0.3)
- BuildTools+: ocamldoc
- Install: true
- XOCamlbuildPath: .
- XOCamlbuildLibraries: containers.string
-
-Document containers_advanced
- Title: Containers_advanced docs
- Type: ocamlbuild (0.3)
- BuildTools+: ocamldoc
- Install: true
- XOCamlbuildPath: .
- XOCamlbuildLibraries: containers.advanced
-
-Document containers_lwt
- Title: Containers_lwt docs
- Type: ocamlbuild (0.3)
- BuildTools+: ocamldoc
- Install: true
- XOCamlbuildPath: .
- XOCamlbuildLibraries: containers.lwt
+ XOCamlbuildExtraArgs:
+ "-docflags '-colorize-code -short-functors -charset utf-8'"
+ XOCamlbuildLibraries:
+ containers, containers.misc, containers.iter, containers.data,
+ containers.string, containers.pervasives, containers.bigarray,
+ containers.advanced, containers.io, containers.sexp,
+ containers.lwt
Executable run_benchs
Path: benchs/
@@ -162,7 +158,8 @@ Executable run_benchs
Build$: flag(bench) && flag(misc)
MainIs: run_benchs.ml
BuildDepends: containers, containers.misc, containers.advanced,
- containers.string, benchmark
+ containers.data, containers.string, containers.iter,
+ sequence, gen, benchmark
Executable bench_hash
Path: benchs/
@@ -170,7 +167,7 @@ Executable bench_hash
CompiledObject: native
Build$: flag(bench) && flag(misc)
MainIs: bench_hash.ml
- BuildDepends: containers,containers.misc
+ BuildDepends: containers, containers.misc
Executable bench_conv
Path: benchs/
@@ -178,7 +175,7 @@ Executable bench_conv
CompiledObject: native
Build$: flag(bench)
MainIs: bench_conv.ml
- BuildDepends: containers,benchmark
+ BuildDepends: containers, benchmark, gen
Executable test_levenshtein
Path: tests/
@@ -186,15 +183,7 @@ Executable test_levenshtein
CompiledObject: native
Build$: flag(tests)
MainIs: test_levenshtein.ml
- BuildDepends: containers,qcheck,containers.string
-
-Executable test_lwt
- Path: tests/lwt/
- Install: false
- CompiledObject: best
- Build$: flag(tests) && flag(lwt)
- MainIs: test_Behavior.ml
- BuildDepends: containers,lwt,lwt.unix,oUnit,containers.lwt
+ BuildDepends: containers, qcheck, containers.string
Executable test_threads
Path: tests/lwt/
@@ -202,7 +191,7 @@ Executable test_threads
CompiledObject: best
Build$: flag(tests) && flag(thread)
MainIs: test_Future.ml
- BuildDepends: containers,threads,oUnit,containers.lwt
+ BuildDepends: containers, threads, oUnit, containers.lwt
PreBuildCommand: make qtest-gen
@@ -212,8 +201,10 @@ Executable run_qtest
CompiledObject: native
MainIs: run_qtest.ml
Build$: flag(tests)
- BuildDepends: containers, containers.misc, containers.string,
- oUnit, QTest2Lib
+ BuildDepends: containers, containers.misc, containers.string, containers.iter,
+ containers.io, containers.advanced, containers.sexp,
+ containers.bigarray,
+ sequence, gen, oUnit, QTest2Lib
Executable run_tests
Path: tests/
@@ -221,26 +212,20 @@ Executable run_tests
CompiledObject: native
MainIs: run_tests.ml
Build$: flag(tests) && flag(misc)
- BuildDepends: containers, oUnit, qcheck, containers.misc
+ BuildDepends: containers, containers.data, oUnit, sequence, gen,
+ qcheck, containers.misc
Test all
Command: make test-all
TestTools: run_tests, run_qtest
Run$: flag(tests) && flag(misc)
-Executable web_pwd
- Path: examples/cgi/
- Install: false
- MainIs: web_pwd.ml
- Build$: flag(cgi)
- BuildDepends: containers, containers.cgi, threads, CamlGI
-
Executable lambda
Path: examples/
Install: false
MainIs: lambda.ml
Build$: flag(misc)
- BuildDepends: containers,containers.misc
+ BuildDepends: containers, containers.misc
Executable id_sexp
Path: examples/
@@ -248,7 +233,15 @@ Executable id_sexp
CompiledObject: native
MainIs: id_sexp.ml
Build$: flag(misc)
- BuildDepends: containers
+ BuildDepends: containers.sexp
+
+Executable id_sexp2
+ Path: examples/
+ Install: false
+ CompiledObject: native
+ MainIs: id_sexp2.ml
+ Build$: flag(misc)
+ BuildDepends: containers.sexp
SourceRepository head
Type: git
diff --git a/_tags b/_tags
index 62463c8e..0c6ac720 100644
--- a/_tags
+++ b/_tags
@@ -1,5 +1,5 @@
# OASIS_START
-# DO NOT EDIT (digest: 87b09f8c85905e63062b223fad9468e9)
+# DO NOT EDIT (digest: 616ce46d4cb6f4ca580b6de54c9a1d70)
# Ignore VCS directories, you can use the same kind of rule outside
# OASIS_START/STOP if you want to exclude directories that contains
# useless stuff for the build process
@@ -15,104 +15,119 @@ true: annot, bin_annot
"_darcs": -traverse
"_darcs": not_hygienic
# Library containers
-"core/containers.cmxs": use_containers
-: package(bytes)
+"src/core/containers.cmxs": use_containers
+: package(bytes)
+# Library containers_io
+"src/io/containers_io.cmxs": use_containers_io
+: package(bytes)
+# Library containers_sexp
+"src/sexp/containers_sexp.cmxs": use_containers_sexp
+: package(bytes)
+# Library containers_data
+"src/data/containers_data.cmxs": use_containers_data
+# Library containers_iter
+"src/iter/containers_iter.cmxs": use_containers_iter
# Library containers_string
-"string/containers_string.cmxs": use_containers_string
-"string/KMP.cmx": for-pack(Containers_string)
-"string/levenshtein.cmx": for-pack(Containers_string)
+"src/string/containers_string.cmxs": use_containers_string
+"src/string/KMP.cmx": for-pack(Containers_string)
+"src/string/levenshtein.cmx": for-pack(Containers_string)
# Library containers_advanced
-"advanced/containers_advanced.cmxs": use_containers_advanced
-"advanced/CCLinq.cmx": for-pack(Containers_advanced)
-"advanced/CCBatch.cmx": for-pack(Containers_advanced)
-"advanced/CCCat.cmx": for-pack(Containers_advanced)
-"advanced/CCMonadIO.cmx": for-pack(Containers_advanced)
-: package(bytes)
-: use_containers
+"src/advanced/containers_advanced.cmxs": use_containers_advanced
+"src/advanced/CCLinq.cmx": for-pack(Containers_advanced)
+"src/advanced/CCBatch.cmx": for-pack(Containers_advanced)
+"src/advanced/CCCat.cmx": for-pack(Containers_advanced)
+"src/advanced/CCMonadIO.cmx": for-pack(Containers_advanced)
+: package(bytes)
+: package(sequence)
+: use_containers
+# Library containers_bigarray
+"src/bigarray/containers_bigarray.cmxs": use_containers_bigarray
+: package(bigarray)
+: package(bytes)
+: use_containers
# Library containers_pervasives
-"pervasives/containers_pervasives.cmxs": use_containers_pervasives
-: package(bytes)
-: use_containers
+"src/pervasives/containers_pervasives.cmxs": use_containers_pervasives
+: package(bytes)
+: use_containers
# Library containers_misc
-"misc/containers_misc.cmxs": use_containers_misc
-"misc/fHashtbl.cmx": for-pack(Containers_misc)
-"misc/flatHashtbl.cmx": for-pack(Containers_misc)
-"misc/hashset.cmx": for-pack(Containers_misc)
-"misc/heap.cmx": for-pack(Containers_misc)
-"misc/lazyGraph.cmx": for-pack(Containers_misc)
-"misc/persistentGraph.cmx": for-pack(Containers_misc)
-"misc/pHashtbl.cmx": for-pack(Containers_misc)
-"misc/skipList.cmx": for-pack(Containers_misc)
-"misc/splayTree.cmx": for-pack(Containers_misc)
-"misc/splayMap.cmx": for-pack(Containers_misc)
-"misc/univ.cmx": for-pack(Containers_misc)
-"misc/bij.cmx": for-pack(Containers_misc)
-"misc/piCalculus.cmx": for-pack(Containers_misc)
-"misc/RAL.cmx": for-pack(Containers_misc)
-"misc/unionFind.cmx": for-pack(Containers_misc)
-"misc/smallSet.cmx": for-pack(Containers_misc)
-"misc/absSet.cmx": for-pack(Containers_misc)
-"misc/CSM.cmx": for-pack(Containers_misc)
-"misc/tTree.cmx": for-pack(Containers_misc)
-"misc/printBox.cmx": for-pack(Containers_misc)
-"misc/hGraph.cmx": for-pack(Containers_misc)
-"misc/automaton.cmx": for-pack(Containers_misc)
-"misc/conv.cmx": for-pack(Containers_misc)
-"misc/bidir.cmx": for-pack(Containers_misc)
-"misc/iteratee.cmx": for-pack(Containers_misc)
-"misc/bTree.cmx": for-pack(Containers_misc)
-"misc/ty.cmx": for-pack(Containers_misc)
-"misc/cause.cmx": for-pack(Containers_misc)
-"misc/AVL.cmx": for-pack(Containers_misc)
-"misc/parseReact.cmx": for-pack(Containers_misc)
-"misc/mixtbl.cmx": for-pack(Containers_misc)
-: package(bytes)
-: package(unix)
-: use_containers
+"src/misc/containers_misc.cmxs": use_containers_misc
+"src/misc/fHashtbl.cmx": for-pack(Containers_misc)
+"src/misc/flatHashtbl.cmx": for-pack(Containers_misc)
+"src/misc/hashset.cmx": for-pack(Containers_misc)
+"src/misc/heap.cmx": for-pack(Containers_misc)
+"src/misc/lazyGraph.cmx": for-pack(Containers_misc)
+"src/misc/persistentGraph.cmx": for-pack(Containers_misc)
+"src/misc/pHashtbl.cmx": for-pack(Containers_misc)
+"src/misc/skipList.cmx": for-pack(Containers_misc)
+"src/misc/splayTree.cmx": for-pack(Containers_misc)
+"src/misc/splayMap.cmx": for-pack(Containers_misc)
+"src/misc/univ.cmx": for-pack(Containers_misc)
+"src/misc/bij.cmx": for-pack(Containers_misc)
+"src/misc/piCalculus.cmx": for-pack(Containers_misc)
+"src/misc/RAL.cmx": for-pack(Containers_misc)
+"src/misc/unionFind.cmx": for-pack(Containers_misc)
+"src/misc/smallSet.cmx": for-pack(Containers_misc)
+"src/misc/absSet.cmx": for-pack(Containers_misc)
+"src/misc/CSM.cmx": for-pack(Containers_misc)
+"src/misc/tTree.cmx": for-pack(Containers_misc)
+"src/misc/printBox.cmx": for-pack(Containers_misc)
+"src/misc/hGraph.cmx": for-pack(Containers_misc)
+"src/misc/automaton.cmx": for-pack(Containers_misc)
+"src/misc/conv.cmx": for-pack(Containers_misc)
+"src/misc/bidir.cmx": for-pack(Containers_misc)
+"src/misc/iteratee.cmx": for-pack(Containers_misc)
+"src/misc/bTree.cmx": for-pack(Containers_misc)
+"src/misc/ty.cmx": for-pack(Containers_misc)
+"src/misc/cause.cmx": for-pack(Containers_misc)
+"src/misc/AVL.cmx": for-pack(Containers_misc)
+"src/misc/parseReact.cmx": for-pack(Containers_misc)
+: package(bytes)
+: use_containers
+: use_containers_data
# Library containers_thread
-"threads/containers_thread.cmxs": use_containers_thread
-: package(bytes)
-: package(threads)
-: use_containers
+"src/threads/containers_thread.cmxs": use_containers_thread
+: package(bytes)
+: package(threads)
+: use_containers
# Library containers_lwt
-"lwt/containers_lwt.cmxs": use_containers_lwt
-"lwt/behavior.cmx": for-pack(Containers_lwt)
-"lwt/lwt_automaton.cmx": for-pack(Containers_lwt)
-"lwt/lwt_actor.cmx": for-pack(Containers_lwt)
-: package(bytes)
-: package(lwt)
-: package(lwt.unix)
-: package(unix)
-: use_containers
-: use_containers_misc
-# Library containers_cgi
-"cgi/containers_cgi.cmxs": use_containers_cgi
-: package(CamlGI)
-: package(bytes)
-: use_containers
+"src/lwt/containers_lwt.cmxs": use_containers_lwt
+"src/lwt/lwt_automaton.cmx": for-pack(Containers_lwt)
+"src/lwt/lwt_actor.cmx": for-pack(Containers_lwt)
+: package(bytes)
+: package(lwt)
+: use_containers
+: use_containers_data
+: use_containers_misc
# Executable run_benchs
"benchs/run_benchs.native": package(benchmark)
"benchs/run_benchs.native": package(bytes)
-"benchs/run_benchs.native": package(unix)
+"benchs/run_benchs.native": package(gen)
+"benchs/run_benchs.native": package(sequence)
"benchs/run_benchs.native": use_containers
"benchs/run_benchs.native": use_containers_advanced
+"benchs/run_benchs.native": use_containers_data
+"benchs/run_benchs.native": use_containers_iter
"benchs/run_benchs.native": use_containers_misc
"benchs/run_benchs.native": use_containers_string
+: package(sequence)
: use_containers_advanced
+: use_containers_iter
: use_containers_string
# Executable bench_hash
"benchs/bench_hash.native": package(bytes)
-"benchs/bench_hash.native": package(unix)
"benchs/bench_hash.native": use_containers
+"benchs/bench_hash.native": use_containers_data
"benchs/bench_hash.native": use_containers_misc
-: package(unix)
+: use_containers_data
: use_containers_misc
# Executable bench_conv
"benchs/bench_conv.native": package(benchmark)
"benchs/bench_conv.native": package(bytes)
+"benchs/bench_conv.native": package(gen)
"benchs/bench_conv.native": use_containers
: package(benchmark)
: package(bytes)
+: package(gen)
: use_containers
# Executable test_levenshtein
"tests/test_levenshtein.native": package(bytes)
@@ -120,89 +135,90 @@ true: annot, bin_annot
"tests/test_levenshtein.native": use_containers
"tests/test_levenshtein.native": use_containers_string
: use_containers_string
-# Executable test_lwt
-: package(bytes)
-: package(lwt)
-: package(lwt.unix)
-: package(oUnit)
-: package(unix)
-: use_containers
-: use_containers_lwt
-: use_containers_misc
# Executable test_threads
: package(bytes)
: package(lwt)
-: package(lwt.unix)
: package(oUnit)
: package(threads)
-: package(unix)
: use_containers
+: use_containers_data
: use_containers_lwt
: use_containers_misc
: package(bytes)
: package(lwt)
-: package(lwt.unix)
: package(oUnit)
: package(threads)
-: package(unix)
: use_containers
+: use_containers_data
: use_containers_lwt
: use_containers_misc
# Executable run_qtest
"qtest/run_qtest.native": package(QTest2Lib)
+"qtest/run_qtest.native": package(bigarray)
"qtest/run_qtest.native": package(bytes)
+"qtest/run_qtest.native": package(gen)
"qtest/run_qtest.native": package(oUnit)
-"qtest/run_qtest.native": package(unix)
+"qtest/run_qtest.native": package(sequence)
"qtest/run_qtest.native": use_containers
+"qtest/run_qtest.native": use_containers_advanced
+"qtest/run_qtest.native": use_containers_bigarray
+"qtest/run_qtest.native": use_containers_data
+"qtest/run_qtest.native": use_containers_io
+"qtest/run_qtest.native": use_containers_iter
"qtest/run_qtest.native": use_containers_misc
+"qtest/run_qtest.native": use_containers_sexp
"qtest/run_qtest.native": use_containers_string
: package(QTest2Lib)
+: package(bigarray)
: package(bytes)
+: package(gen)
: package(oUnit)
-: package(unix)
+: package(sequence)
: use_containers
+: use_containers_advanced
+: use_containers_bigarray
+: use_containers_data
+: use_containers_io
+: use_containers_iter
: use_containers_misc
+: use_containers_sexp
: use_containers_string
# Executable run_tests
"tests/run_tests.native": package(bytes)
+"tests/run_tests.native": package(gen)
"tests/run_tests.native": package(oUnit)
"tests/run_tests.native": package(qcheck)
-"tests/run_tests.native": package(unix)
+"tests/run_tests.native": package(sequence)
"tests/run_tests.native": use_containers
+"tests/run_tests.native": use_containers_data
"tests/run_tests.native": use_containers_misc
: package(bytes)
+: package(gen)
: package(oUnit)
: package(qcheck)
-: package(unix)
+: package(sequence)
: use_containers
+: use_containers_data
: use_containers_misc
-# Executable web_pwd
-"examples/cgi/web_pwd.byte": package(CamlGI)
-"examples/cgi/web_pwd.byte": package(bytes)
-"examples/cgi/web_pwd.byte": package(threads)
-"examples/cgi/web_pwd.byte": use_containers
-"examples/cgi/web_pwd.byte": use_containers_cgi
-: package(CamlGI)
-: package(bytes)
-: package(threads)
-: use_containers
-: use_containers_cgi
# Executable lambda
"examples/lambda.byte": package(bytes)
-"examples/lambda.byte": package(unix)
"examples/lambda.byte": use_containers
+"examples/lambda.byte": use_containers_data
"examples/lambda.byte": use_containers_misc
-: package(unix)
+: use_containers
+: use_containers_data
: use_containers_misc
# Executable id_sexp
"examples/id_sexp.native": package(bytes)
-"examples/id_sexp.native": use_containers
+"examples/id_sexp.native": use_containers_sexp
+# Executable id_sexp2
+"examples/id_sexp2.native": package(bytes)
+"examples/id_sexp2.native": use_containers_sexp
: package(bytes)
-: use_containers
+: use_containers_sexp
# OASIS_STOP
: thread
-: thread
-: -traverse
-: -traverse
-: inline(25)
-<{string,core}/**/*.ml>: warn_A, warn(-4), warn(-44)
+: thread
+: inline(25)
+ and not : warn_A, warn(-4), warn(-44)
+true: no_alias_deps
diff --git a/benchs/bench_conv.ml b/benchs/bench_conv.ml
index c117fda8..7e958f36 100644
--- a/benchs/bench_conv.ml
+++ b/benchs/bench_conv.ml
@@ -79,11 +79,11 @@ let () =
bench_list [1,2; 3,4; 5,6; 7,8; 9,10];
let open CCFun in
- let l = CCGen.(1 -- 100 |> map (fun x->x,x) |> to_rev_list) in
+ let l = Gen.(1 -- 100 |> map (fun x->x,x) |> to_rev_list) in
Printf.printf "list of %d elements...\n" (List.length l);
bench_list l;
- let l = CCGen.(repeat Point.p |> take 10 |> to_rev_list) in
+ let l = Gen.(repeat Point.p |> take 10 |> to_rev_list) in
Printf.printf "list of %d points...\n" (List.length l);
bench_point_list l;
diff --git a/benchs/run_benchs.ml b/benchs/run_benchs.ml
index ec53abbd..3bde113e 100644
--- a/benchs/run_benchs.ml
+++ b/benchs/run_benchs.ml
@@ -480,8 +480,8 @@ module Iter = struct
(** {2 Sequence/Gen} *)
let bench_fold n =
- let seq () = CCSequence.fold (+) 0 CCSequence.(0 --n) in
- let gen () = CCGen.fold (+) 0 CCGen.(0 -- n) in
+ let seq () = Sequence.fold (+) 0 Sequence.(0 --n) in
+ let gen () = Gen.fold (+) 0 Gen.(0 -- n) in
let klist () = CCKList.fold (+) 0 CCKList.(0 -- n) in
CCBench.throughputN 3
[ "sequence.fold", seq, ();
@@ -490,10 +490,10 @@ module Iter = struct
]
let bench_flat_map n =
- let seq () = CCSequence.(
+ let seq () = Sequence.(
0 -- n |> flat_map (fun x -> x-- (x+10)) |> fold (+) 0
)
- and gen () = CCGen.(
+ and gen () = Gen.(
0 -- n |> flat_map (fun x -> x-- (x+10)) |> fold (+) 0
)
and klist () = CCKList.(
@@ -509,12 +509,12 @@ module Iter = struct
let bench_iter n =
let seq () =
let i = ref 2 in
- CCSequence.(
+ Sequence.(
1 -- n |> iter (fun x -> i := !i * x)
)
and gen () =
let i = ref 2 in
- CCGen.(
+ Gen.(
1 -- n |> iter (fun x -> i := !i * x)
)
and klist () =
diff --git a/cgi/toWeb.ml b/cgi/toWeb.ml
deleted file mode 100644
index 1d2f2fc1..00000000
--- a/cgi/toWeb.ml
+++ /dev/null
@@ -1,358 +0,0 @@
-
-(*
-copyright (c) 2013, simon cruanes
-all rights reserved.
-
-redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Expose the State of a Program to the Web}
-
- We export some values (and associated functions for converting them to
- html, and update them) as a FastCGI interface.
-
- This module depends on CamlGI.
-*)
-
-(** {2 Some combinators to build HTML documents} *)
-
-module HTML = struct
- type t =
- | Str of string (* content *)
- | List of t list
- | Url of url
- | Img of image
- | Concat of t list
- | H of int * t
- | Link of link
- | Tag of string * t
- | TagWith of string * (string * string) list * t
- and url = {
- url_alt : string option;
- url_url : string;
- url_descr : string;
- }
- and image = {
- img_alt : string option;
- img_url : string;
- }
- and link = {
- link_rel : string;
- link_url : string;
- }
-
- let str s = Str s
-
- let bprintf format =
- let buffer = Buffer.create 64 in
- let r = ref (str "") in
- Printf.kbprintf
- (fun x -> r := str (Buffer.contents buffer))
- buffer
- format;
- !r
-
- let sprintf format =
- let r = ref (str "") in
- Printf.ksprintf
- (fun s -> r := str s)
- format;
- !r
-
- let list l = List l
-
- let url ?alt ~url ~descr = Url {
- url_alt = alt;
- url_url = url;
- url_descr = descr;
- }
-
- let img ?alt url = Img {
- img_alt = alt;
- img_url = url;
- }
-
- let append a b = Concat [a; b]
-
- let concat l = Concat l
-
- let h1 x = H (1, x)
-
- let h2 x = H (2, x)
-
- let h3 x = H (3, x)
-
- let h n x = H (n, x)
-
- let p x = Tag ("p", x)
-
- let div ?id ?class_ x =
- match id, class_ with
- | None, None -> Tag ("div", x)
- | Some i, None -> TagWith ("div", ["id", i], x)
- | None, Some c -> TagWith ("div", ["class", c], x)
- | Some i, Some c -> TagWith ("div", ["id", i; "class", c], x)
-
- let span ?id ?class_ x =
- match id, class_ with
- | None, None -> Tag ("span", x)
- | Some i, None -> TagWith ("span", ["id", i], x)
- | None, Some c -> TagWith ("span", ["class", c], x)
- | Some i, Some c -> TagWith ("span", ["id", i; "class", c], x)
-
- let link ~rel ~url = Link {
- link_rel = rel;
- link_url = url;
- }
-
- let head x = Tag ("head", x)
-
- let body x = Tag ("body", x)
-
- let html x = Tag ("html", x)
-
- let _to_hex n = match n with
- | _ when n >= 0 && n < 10 -> Char.chr (Char.code '0' + n)
- | 10 -> 'A'
- | 11 -> 'B'
- | 12 -> 'C'
- | 13 -> 'D'
- | 14 -> 'E'
- | 15 -> 'F'
- | _ -> failwith "not an hexadecimal digit"
-
- let _encode_char buf c =
- Buffer.add_string buf "";
- let h, l = Char.code c / 16, Char.code c mod 16 in
- Buffer.add_char buf (_to_hex h);
- Buffer.add_char buf (_to_hex l)
-
- let encode str =
- let b = Buffer.create (String.length str + 10) in
- for i = 0 to String.length str - 1 do
- match str.[i] with
- | ';' | '/' | '?' | ':' | '@' | '&' | '=' | '+' | '$' | ',' | '<'
- | '>' | '#' | '%' | '"' | '{' | '}' | '|' | '\\' | '^' | '[' | ']'
- | '`' -> _encode_char b str.[i]
- | c when Char.code c < 32 -> _encode_char b str.[i]
- | c when Char.code c > 127 -> _encode_char b str.[i]
- | _ -> Buffer.add_char b str.[i]
- done;
- Buffer.contents b
-
- (* real rendering is always into a buffer (for now) *)
- let rec to_buf buf x =
- match x with
- | Str s -> Buffer.add_string buf (encode s)
- | List l ->
- Buffer.add_string buf "";
- List.iter
- (fun y -> Printf.bprintf buf "- %a
" to_buf y)
- l;
- Buffer.add_string buf "
"
- | Url url ->
- begin match url.url_alt with
- | None ->
- Printf.bprintf buf "%s" url.url_url
- (encode url.url_descr)
- | Some alt ->
- Printf.bprintf buf "%s"
- url.url_url (encode alt) (encode url.url_descr)
- end
- | Img i -> failwith "img: not implemented"
- | Concat l ->
- List.iteri
- (fun i y ->
- if i > 0 then Buffer.add_char buf ' ';
- to_buf buf y)
- l
- | H (n, y) ->
- Printf.bprintf buf " %a " n to_buf y n
- | Link _ -> failwith "link: not implemented"
- | Tag (str, y) -> Printf.bprintf buf "<%s> %a %s>" str to_buf y str
- | TagWith (str, attrs, y) ->
- Printf.bprintf buf "<%s " str;
- List.iter (fun (name,attr) -> Printf.bprintf buf "%s=\"%s\"" name attr) attrs;
- Printf.bprintf buf "> %a %s>" to_buf y str
-
- let render x =
- let buf = Buffer.create 256 in
- to_buf buf x;
- Buffer.contents buf
-
- let to_chan oc x =
- let buf = Buffer.create 256 in
- to_buf buf x;
- Buffer.output_buffer oc buf
-end
-
-(** {2 Stateful Object on the Web} *)
-
-module State = struct
- type 'a t = {
- mutable content : 'a;
- mutable callbacks : ('a -> unit) list;
- id : ('a -> string) option;
- export : 'a -> HTML.t;
- update : (string * string) list -> 'a -> 'a;
- } (** A value that can be exposed to the Web.
- The [export] function is used to print the current state of
- the object into HTML (when requested).
- The [update] optional function can be used to update
- the value, given a query with parameters. *)
-
- type wrap = Wrap : 'a t -> wrap
- (** Hides the type parameter in a GADT. *)
-
- let create ?(update=fun _ x -> x) ?id ~export content = {
- content;
- export;
- id;
- callbacks = [];
- update;
- }
-
- let on_change st f =
- st.callbacks <- f :: st.callbacks
-
- let handle_request st req =
- let cgi = new CamlGI.Cgi.cgi req in
- (* update value? *)
- try
- let x = st.content in
- let params = cgi#params in
- (* update [x] using the parameters? *)
- let y = st.update params x in
- let changed = match st.id with
- | None -> x != y
- | Some id -> id x <> id y
- in
- (* notify callbacks that we have a new object *)
- if changed then
- List.iter (fun f -> f y) st.callbacks;
- (* now print [y] *)
- (* TODO: add a head, declaration, etc. *)
- let html = st.export y in
- let final_output = HTML.render html in
- (* render output *)
- let template = object
- method output f = f final_output
- end in
- cgi#template template
- with e ->
- let msg = Printf.sprintf "error: %s" (Printexc.to_string e) in
- cgi#log msg
-end
-
-(** {2 Routing} *)
-
-module Router = struct
- type t = {
- mutable default : State.wrap;
- log : out_channel option;
- tbl : (string, State.wrap) Hashtbl.t;
- }
-
- let __default =
- State.Wrap (State.create ~export:HTML.str "")
-
- let _log router fmt = match router.log with
- | None ->
- Printf.ifprintf stdout fmt
- | Some oc ->
- Printf.kfprintf
- (fun oc ->
- output_char oc '\n';
- flush oc)
- oc
- fmt
-
- let create ?(default=__default) ?log () =
- let router = {
- default;
- log;
- tbl = Hashtbl.create 15;
- } in
- _log router "new router created";
- router
-
- let default router default =
- router.default <- default
-
- let unregister router name =
- Hashtbl.remove router.tbl name
-
- let register ?(weak=false) router name state =
- if Hashtbl.mem router.tbl name
- then failwith "Router: name already registered"
- else begin
- Hashtbl.add router.tbl name state;
- if weak then match state with
- | State.Wrap st ->
- Gc.finalise (fun _ -> unregister router name) st.State.content
- end
-
- let add_list router l =
- List.iter
- (fun (name, state) -> register router name state)
- l
-
- let to_list router =
- Hashtbl.fold
- (fun name state acc -> (name,state) :: acc)
- router.tbl []
-
- let random_id () =
- CamlGI.Cgi.random_sessionid ()
-
- let handle_request router req =
- let cgi = new CamlGI.Cgi.cgi req in
- let url = cgi#url () in
- let st =
- try
- let last_part_i = String.rindex url '/' in
- let last_part = String.sub url (last_part_i+1) (String.length url -last_part_i-1) in
- _log router "received request for url /%s" last_part;
- Hashtbl.find router.tbl last_part
- with Not_found ->
- router.default
- in
- match st with
- | State.Wrap st -> State.handle_request st req
-end
-
-(** {2 Main Interface} *)
-
-let serve_state ?sockfile ?sockaddr st =
- match sockfile with
- | None ->
- CamlGI.Cgi.register_script ?sockaddr (State.handle_request st)
- | Some f ->
- let sockaddr = Unix.ADDR_UNIX f in
- CamlGI.Cgi.register_script ~sockaddr (State.handle_request st)
-
-let serve_router ?sockfile ?sockaddr router =
- match sockfile with
- | None ->
- CamlGI.Cgi.register_script ?sockaddr (Router.handle_request router)
- | Some f ->
- let sockaddr = Unix.ADDR_UNIX f in
- CamlGI.Cgi.register_script ~sockaddr (Router.handle_request router)
diff --git a/cgi/toWeb.mli b/cgi/toWeb.mli
deleted file mode 100644
index b6e3eb40..00000000
--- a/cgi/toWeb.mli
+++ /dev/null
@@ -1,208 +0,0 @@
-
-(*
-copyright (c) 2013, simon cruanes
-all rights reserved.
-
-redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Expose the State of a Program to the Web}
-
- We export some values (and associated functions for converting them to
- html, and update them) as a FastCGI interface.
-
- This module depends on CamlGI.
-*)
-
-(** {2 Some combinators to build HTML documents} *)
-
-module HTML : sig
- type t
- (** A html document. Encoding is assumed to be UTF8 for now. *)
-
- val str : string -> t
- (** Simple string *)
-
- val bprintf : ('a, Buffer.t, unit, unit) format4 -> t
- (** Use a buffer printer to render a string. Shortcut for {!str} *)
-
- val sprintf : ('a, unit, string, unit) format4 -> t
- (** Use a string printer to render into a string. Shortcut for {!str} *)
-
- val list : t list -> t
- (** Build a list of items *)
-
- val url : ?alt:string -> url:string -> descr:string -> t
- (** build an URL tag. *)
-
- val img : ?alt:string -> string -> t
- (** Link to an image *)
-
- val append : t -> t -> t
- (** Concatenation of two documents *)
-
- val concat : t list -> t
- (** Concatenation of html documents *)
-
- val h1 : t -> t
-
- val h2 : t -> t
-
- val h3 : t -> t
-
- val h : int -> t -> t
- (** Title of level parametrized by the integer *)
-
- val p : t -> t
- (** Paragraph *)
-
- val div : ?id:string -> ?class_:string -> t -> t
- (** Div tag, to specify a block *)
-
- val span : ?id:string -> ?class_:string -> t -> t
- (** Non semantic tag, mostly useful for CSS *)
-
- val link : rel:string -> url:string -> t
- (** Link (for head) *)
-
- val head : t -> t
- (** Head part of a document *)
-
- val body : t -> t
- (** Body part of a document *)
-
- val html : t -> t
- (** The whole document *)
-
- val render : t -> string
- (** Print into a string *)
-
- val to_buf : Buffer.t -> t -> unit
- (** Print in the buffer *)
-
- val to_chan : out_channel -> t -> unit
- (** Print on the channel *)
-end
-
-(** {2 Stateful Object on the Web} *)
-
-(** This module defines how to bundle an OCaml value (possibly
- stateful) with functions that export it to HTML,
- and possibly update it from a CGI request.
-*)
-
-module State : sig
- type 'a t
- (** A value that can be exposed to the web. *)
-
- type wrap = Wrap : 'a t -> wrap
- (** Hides the type parameter in a GADT. Useful for {!Router}. *)
-
- val create : ?update:((string*string) list -> 'a -> 'a) ->
- ?id:('a -> string) ->
- export:('a -> HTML.t) ->
- 'a ->
- 'a t
- (** Create a value that can be exposed to the Web.
- @param export function used to print the current state of
- the object into HTML (when requested).
- @param update optional function that can be used to update
- the value, given a query with parameters.
- @param id optional function that maps a value to a (unique)
- string. Can be used to obtain a unique URL for this value. *)
-
- val on_change : 'a t -> ('a -> unit) -> unit
- (** Register a callback that will be called everytime the value
- is updated. Physical equality is used to determine whether
- the value changed if no [id] function was provided;
- otherwise, [id] is used to check whether the old and the new
- strings are equal. *)
-
- val handle_request : 'a t -> CamlGI.Cgi.Request.t -> unit
- (** Handle the incoming request. It replies to the request by
- possibly updating the local state, and
- object. *)
-end
-
-
-(** {2 Routing} *)
-
-module Router : sig
- type t
- (** An URL router. It dispatches incoming requests to registered
- {!State.t} values depending on the request's URL. *)
-
- val create : ?default:State.wrap -> ?log:out_channel -> unit -> t
- (** New router.
- @param log a channel on which to log events (incoming requests)
- @param default a default object to expose, for incorrect routes
- *)
-
- val default : t -> State.wrap -> unit
- (** Set the default handler, for incorrect routes (for which no
- object is registered) or for routing the root url *)
-
- val register : ?weak:bool -> t -> string -> State.wrap -> unit
- (** Register a state object (see {!State}) under a given path.
- Right now routing only dispatches at one level, there is no
- tree-like structure, only a flat "directory" of objects.
-
- @param weak (default false) if true, the object will unregister itself
- when it's garbage collected. Only works if the type of the wrapped
- object is heap allocated.
-
- @raise Failure if the name is already taken
- @raise Invalid_argument if [weak] is true and no finalizer can be
- registered. *)
-
- val unregister : t -> string -> unit
- (** Remove a stateful value *)
-
- val add_list : t -> (string * State.wrap) list -> unit
- (** Register several handlers.
- @raise Failure if it meets an already registered handler *)
-
- val to_list : t -> (string * State.wrap) list
- (** Currently registered objects *)
-
- val random_id : unit -> string
- (** Fresh, random ID that can be used for registering temporary objects *)
-
- val handle_request : t -> CamlGI.Cgi.Request.t -> unit
- (** Handle the incoming request, by routing to an appropriate
- object. *)
-end
-
-(** {2 Main interface} *)
-
-(* TODO: interface with {! LazyGraph}. A (string, html.t, string) graph
- maps naturally to URLs and simplifies routing. *)
-
-val serve_state : ?sockfile:string -> ?sockaddr:Unix.sockaddr ->
- 'a State.t -> unit
- (** Serve incoming requests using a single object.
- @param sockfile the unix file to use as a socket *)
-
-val serve_router : ?sockfile:string -> ?sockaddr:Unix.sockaddr ->
- Router.t -> unit
- (** Shortcut. It calls {!CamlGI.Cgi.register_script} with a callback
- that forwards requests to the given Router.
- @param sockfile the unix file to use as a socket *)
diff --git a/containers.odocl b/containers.odocl
index 64a636bc..b9745656 100644
--- a/containers.odocl
+++ b/containers.odocl
@@ -1,39 +1,77 @@
# OASIS_START
-# DO NOT EDIT (digest: ce652946b9e4e3d4bbad78e220466df8)
-core/CCVector
-core/CCDeque
-core/CCGen
-core/Gen_intf
-core/CCSequence
-core/CCFQueue
-core/CCMultiMap
-core/CCMultiSet
-core/CCBV
-core/CCPrint
-core/CCPersistentHashtbl
-core/CCError
-core/CCHeap
-core/CCList
-core/CCOpt
-core/CCPair
-core/CCFun
-core/CCHash
-core/CCKList
-core/CCInt
-core/CCBool
-core/CCFloat
-core/CCArray
-core/CCOrd
-core/CCIO
-core/CCRandom
-core/CCKTree
-core/CCTrie
-core/CCString
-core/CCHashtbl
-core/CCFlatHashtbl
-core/CCSexp
-core/CCMap
-core/CCCache
-string/KMP
-string/Levenshtein
+# DO NOT EDIT (digest: ffa47e180123d84227a563bc0c3e8534)
+src/core/CCVector
+src/core/CCPrint
+src/core/CCError
+src/core/CCHeap
+src/core/CCList
+src/core/CCOpt
+src/core/CCPair
+src/core/CCFun
+src/core/CCHash
+src/core/CCInt
+src/core/CCBool
+src/core/CCFloat
+src/core/CCArray
+src/core/CCOrd
+src/core/CCRandom
+src/core/CCString
+src/core/CCHashtbl
+src/core/CCMap
+src/misc/FHashtbl
+src/misc/FlatHashtbl
+src/misc/Hashset
+src/misc/Heap
+src/misc/LazyGraph
+src/misc/PersistentGraph
+src/misc/PHashtbl
+src/misc/SkipList
+src/misc/SplayTree
+src/misc/SplayMap
+src/misc/Univ
+src/misc/Bij
+src/misc/PiCalculus
+src/misc/RAL
+src/misc/UnionFind
+src/misc/SmallSet
+src/misc/AbsSet
+src/misc/CSM
+src/misc/TTree
+src/misc/PrintBox
+src/misc/HGraph
+src/misc/Automaton
+src/misc/Conv
+src/misc/Bidir
+src/misc/Iteratee
+src/misc/BTree
+src/misc/Ty
+src/misc/Cause
+src/misc/AVL
+src/misc/ParseReact
+src/iter/CCKTree
+src/iter/CCKList
+src/data/CCMultiMap
+src/data/CCMultiSet
+src/data/CCTrie
+src/data/CCFlatHashtbl
+src/data/CCCache
+src/data/CCPersistentHashtbl
+src/data/CCDeque
+src/data/CCFQueue
+src/data/CCBV
+src/data/CCMixtbl
+src/string/KMP
+src/string/Levenshtein
+src/pervasives/CCPervasives
+src/bigarray/CCBigstring
+src/advanced/CCLinq
+src/advanced/CCBatch
+src/advanced/CCCat
+src/advanced/CCMonadIO
+src/io/CCIO
+src/sexp/CCSexp
+src/sexp/CCSexpStream
+src/sexp/CCSexpM
+src/lwt/Lwt_automaton
+src/lwt/Lwt_actor
# OASIS_STOP
diff --git a/core/CCGen.ml b/core/CCGen.ml
deleted file mode 120000
index 8eb5e88d..00000000
--- a/core/CCGen.ml
+++ /dev/null
@@ -1 +0,0 @@
-../gen/gen.ml
\ No newline at end of file
diff --git a/core/CCGen.mli b/core/CCGen.mli
deleted file mode 100644
index 0d284c22..00000000
--- a/core/CCGen.mli
+++ /dev/null
@@ -1,105 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Generators}
-
-Values of type ['a Gen.t] represent a possibly infinite sequence of values
-of type 'a. One can only iterate once on the sequence, as it is consumed
-by iteration/deconstruction/access. [None] is returned when the generator
-is exhausted. Most functions consume elements.
-
-The submodule {!Restart} provides utilities to work with
-{b restartable generators}, that is, functions [unit -> 'a Gen.t] that
-allow to build as many generators from the same source as needed.
-*)
-
-(** {2 Global type declarations} *)
-
-type 'a t = unit -> 'a option
- (** A generator may be called several times, yielding the next value
- each time. It returns [None] when no elements remain *)
-
-type 'a gen = 'a t
-
-(** {b NOTE}: version informations ("@since" annotations) in CCGen_intf
- will not be reliable, for they will represent versions of Gen
- rather than containers. *)
-module type S = Gen_intf.S
-
-(** {2 Transient generators} *)
-
-val get : 'a t -> 'a option
- (** Get the next value *)
-
-val next : 'a t -> 'a option
- (** Synonym for {!get} *)
-
-val get_exn : 'a t -> 'a
- (** Get the next value, or fails
- @raise Invalid_argument if no element remains *)
-
-val junk : 'a t -> unit
- (** Drop the next value, discarding it. *)
-
-val repeatedly : (unit -> 'a) -> 'a t
- (** Call the same function an infinite number of times (useful for instance
- if the function is a random generator). *)
-
-include S with type 'a t := 'a gen
- (** Operations on {b transient} generators *)
-
-(** {2 Restartable generators} *)
-
-module Restart : sig
- type 'a t = unit -> 'a gen
-
- type 'a restartable = 'a t
-
- include S with type 'a t := 'a restartable
-
- val cycle : 'a t -> 'a t
- (** Cycle through the enum, endlessly. The enum must not be empty. *)
-
- val lift : ('a gen -> 'b) -> 'a t -> 'b
-
- val lift2 : ('a gen -> 'b gen -> 'c) -> 'a t -> 'b t -> 'c
-end
-
-(** {2 Utils} *)
-
-val persistent : 'a t -> 'a Restart.t
- (** Store content of the transient generator in memory, to be able to iterate
- on it several times later. If possible, consider using combinators
- from {!Restart} directly instead. *)
-
-val persistent_lazy : 'a t -> 'a Restart.t
- (** Same as {!persistent}, but consumes the generator on demand (by chunks).
- This allows to make a restartable generator out of an ephemeral one,
- without paying a big cost upfront (nor even consuming it fully).
- @since 0.6.1 *)
-
-val start : 'a Restart.t -> 'a t
- (** Create a new transient generator.
- [start gen] is the same as [gen ()] but is included for readability. *)
diff --git a/core/CCSequence.ml b/core/CCSequence.ml
deleted file mode 120000
index 397a44e3..00000000
--- a/core/CCSequence.ml
+++ /dev/null
@@ -1 +0,0 @@
-../sequence/sequence.ml
\ No newline at end of file
diff --git a/core/CCSequence.mli b/core/CCSequence.mli
deleted file mode 100644
index 476af4db..00000000
--- a/core/CCSequence.mli
+++ /dev/null
@@ -1,624 +0,0 @@
-(*
-copyright (c) 2013, simon cruanes
-all rights reserved.
-
-redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Simple and Efficient Iterators} *)
-
-(** The iterators are designed to allow easy transfer (mappings) between data
- structures, without defining [n^2] conversions between the [n] types. The
- implementation relies on the assumption that a sequence can be iterated
- on as many times as needed; this choice allows for high performance
- of many combinators. However, for transient iterators, the {!persistent}
- function is provided, storing elements of a transient iterator
- in memory; the iterator can then be used several times (See further).
-
- Note that some combinators also return sequences (e.g. {!group}). The
- transformation is computed on the fly every time one iterates over
- the resulting sequence. If a transformation performs heavy computation,
- {!persistent} can also be used as intermediate storage.
-
- Most functions are {b lazy}, i.e. they do not actually use their arguments
- until their result is iterated on. For instance, if one calls {!map}
- on a sequence, one gets a new sequence, but nothing else happens until
- this new sequence is used (by folding or iterating on it).
-
- If a sequence is built from an iteration function that is {b repeatable}
- (i.e. calling it several times always iterates on the same set of
- elements, for instance List.iter or Map.iter), then
- the resulting {!t} object is also repeatable. For {b one-time iter functions}
- such as iteration on a file descriptor or a {!Stream},
- the {!persistent} function can be used to iterate and store elements in
- a memory structure; the result is a sequence that iterates on the elements
- of this memory structure, cheaply and repeatably. *)
-
-type +'a t = ('a -> unit) -> unit
- (** A sequence of values of type ['a]. If you give it a function ['a -> unit]
- it will be applied to every element of the sequence successively. *)
-
-type +'a sequence = 'a t
-
-type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
- (** Sequence of pairs of values of type ['a] and ['b]. *)
-
-(** {2 Build a sequence} *)
-
-val from_iter : (('a -> unit) -> unit) -> 'a t
- (** Build a sequence from a iter function *)
-
-val from_fun : (unit -> 'a option) -> 'a t
- (** Call the function repeatedly until it returns None. This
- sequence is transient, use {!persistent} if needed! *)
-
-val empty : 'a t
- (** Empty sequence. It contains no element. *)
-
-val singleton : 'a -> 'a t
- (** Singleton sequence, with exactly one element. *)
-
-val doubleton : 'a -> 'a -> 'a t
- (** Sequence with exactly two elements
- @since 0.3.4 *)
-
-val cons : 'a -> 'a t -> 'a t
- (** [cons x l] yields [x], then yields from [l].
- Same as [append (singleton x) l]
- @since 0.3.4 *)
-
-
-val snoc : 'a t -> 'a -> 'a t
- (** Same as {!cons} but yields the element after iterating on [l]
- @since 0.3.4 *)
-
-val return : 'a -> 'a t
- (** Synonym to {!singleton}
- @since 0.3.4 *)
-
-val pure : 'a -> 'a t
- (** Synonym to {!singleton}
- @since 0.3.4 *)
-
-val repeat : 'a -> 'a t
- (** Infinite sequence of the same element. You may want to look
- at {!take} and the likes if you iterate on it. *)
-
-val iterate : ('a -> 'a) -> 'a -> 'a t
- (** [iterate f x] is the infinite sequence [x, f(x), f(f(x)), ...] *)
-
-val forever : (unit -> 'b) -> 'b t
- (** Sequence that calls the given function to produce elements.
- The sequence may be transient (depending on the function), and definitely
- is infinite. You may want to use {!take} and {!persistent}. *)
-
-val cycle : 'a t -> 'a t
- (** Cycle forever through the given sequence. Assume the given sequence can
- be traversed any amount of times (not transient). This yields an
- infinite sequence, you should use something like {!take} not to loop
- forever. *)
-
-(** {2 Consume a sequence} *)
-
-val iter : ('a -> unit) -> 'a t -> unit
- (** Consume the sequence, passing all its arguments to the function.
- Basically [iter f seq] is just [seq f]. *)
-
-val iteri : (int -> 'a -> unit) -> 'a t -> unit
- (** Iterate on elements and their index in the sequence *)
-
-val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
- (** Fold over elements of the sequence, consuming it *)
-
-val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
- (** Fold over elements of the sequence and their index, consuming it *)
-
-val map : ('a -> 'b) -> 'a t -> 'b t
- (** Map objects of the sequence into other elements, lazily *)
-
-val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
- (** Map objects, along with their index in the sequence *)
-
-val for_all : ('a -> bool) -> 'a t -> bool
- (** Do all elements satisfy the predicate? *)
-
-val exists : ('a -> bool) -> 'a t -> bool
- (** Exists there some element satisfying the predicate? *)
-
-val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
- (** Is the value a member of the sequence?
- @param eq the equality predicate to use (default [(=)])
- @since 0.3.4 *)
-
-val find : ('a -> 'b option) -> 'a t -> 'b option
- (** Find the first element on which the function doesn't return [None]
- @since 0.3.4 *)
-
-val length : 'a t -> int
- (** How long is the sequence? Forces the sequence. *)
-
-val is_empty : 'a t -> bool
- (** Is the sequence empty? Forces the sequence. *)
-
-(** {2 Transform a sequence} *)
-
-val filter : ('a -> bool) -> 'a t -> 'a t
- (** Filter on elements of the sequence *)
-
-val append : 'a t -> 'a t -> 'a t
- (** Append two sequences. Iterating on the result is like iterating
- on the first, then on the second. *)
-
-val concat : 'a t t -> 'a t
- (** Concatenate a sequence of sequences into one sequence. *)
-
-val flatten : 'a t t -> 'a t
- (** Alias for {!concat} *)
-
-val flatMap : ('a -> 'b t) -> 'a t -> 'b t
- (** Monadic bind. Intuitively, it applies the function to every element of the
- initial sequence, and calls {!concat}. *)
-
-val flat_map : ('a -> 'b t) -> 'a t -> 'b t
- (** Alias to {!flatMap} with a more explicit name
- @since 0.3.4 *)
-
-val fmap : ('a -> 'b option) -> 'a t -> 'b t
- (** Specialized version of {!flatMap} for options. *)
-
-val filter_map : ('a -> 'b option) -> 'a t -> 'b t
- (** Alias to {!fmap} with a more explicit name
- @since 0.3.4 *)
-
-val intersperse : 'a -> 'a t -> 'a t
- (** Insert the single element between every element of the sequence *)
-
-(** {2 Caching} *)
-
-val persistent : 'a t -> 'a t
- (** Iterate on the sequence, storing elements in an efficient internal structure..
- The resulting sequence can be iterated on as many times as needed.
- {b Note}: calling persistent on an already persistent sequence
- will still make a new copy of the sequence! *)
-
-val persistent_lazy : 'a t -> 'a t
- (** Lazy version of {!persistent}. When calling [persistent_lazy s],
- a new sequence [s'] is immediately returned (without actually consuming
- [s]) in constant time; the first time [s'] is iterated on,
- it also consumes [s] and caches its content into a inner data
- structure that will back [s'] for future iterations.
-
- {b warning}: on the first traversal of [s'], if the traversal
- is interrupted prematurely ({!take}, etc.) then [s'] will not be
- memorized, and the next call to [s'] will traverse [s] again.
-
- @since 0.3.4 *)
-
-(** {2 Misc} *)
-
-val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
- (** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time.
- It iterates on elements of the argument sequence immediately,
- before it sorts them. *)
-
-val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
- (** Sort the sequence and remove duplicates. Eager, same as [sort] *)
-
-val group : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
- (** Group equal consecutive elements. *)
-
-val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
- (** Remove consecutive duplicate elements. Basically this is
- like [fun seq -> map List.hd (group seq)]. *)
-
-val product : 'a t -> 'b t -> ('a * 'b) t
- (** Cartesian product of the sequences. When calling [product a b],
- the caller {b MUST} ensure that [b] can be traversed as many times
- as required (several times), possibly by calling {!persistent} on it
- beforehand. *)
-
-val product2 : 'a t -> 'b t -> ('a, 'b) t2
- (** Binary version of {!product}. Same requirements.
- @since 0.3.4 *)
-
-val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
- (** [join ~join_row a b] combines every element of [a] with every
- element of [b] using [join_row]. If [join_row] returns None, then
- the two elements do not combine. Assume that [b] allows for multiple
- iterations. *)
-
-val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
- (** [unfoldr f b] will apply [f] to [b]. If it
- yields [Some (x,b')] then [x] is returned
- and unfoldr recurses with [b']. *)
-
-val scan : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b t
- (** Sequence of intermediate results *)
-
-val max : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
- (** Max element of the sequence, using the given comparison function.
- @return None if the sequence is empty, Some [m] where [m] is the maximal
- element otherwise *)
-
-val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
- (** Min element of the sequence, using the given comparison function.
- see {!max} for more details. *)
-
-val head : 'a t -> 'a option
- (** First element, if any, otherwise [None]
- @since 0.3.4 *)
-
-val head_exn : 'a t -> 'a
- (** First element, if any, fails
- @raise Invalid_argument if the sequence is empty
- @since 0.3.4 *)
-
-val take : int -> 'a t -> 'a t
- (** Take at most [n] elements from the sequence. Works on infinite
- sequences. *)
-
-val take_while : ('a -> bool) -> 'a t -> 'a t
- (** Take elements while they satisfy the predicate, then stops iterating.
- Will work on an infinite sequence [s] if the predicate is false for at
- least one element of [s].
- @since 0.3.4 *)
-
-val drop : int -> 'a t -> 'a t
- (** Drop the [n] first elements of the sequence. Lazy. *)
-
-val drop_while : ('a -> bool) -> 'a t -> 'a t
- (** Predicate version of {!drop}
- @since 0.3.4 *)
-
-val rev : 'a t -> 'a t
- (** Reverse the sequence. O(n) memory and time, needs the
- sequence to be finite. The result is persistent and does
- not depend on the input being repeatable. *)
-
-(** {2 Binary sequences} *)
-
-val empty2 : ('a, 'b) t2
-
-val is_empty2 : (_, _) t2 -> bool
-
-val length2 : (_, _) t2 -> int
-
-val zip : ('a, 'b) t2 -> ('a * 'b) t
-
-val unzip : ('a * 'b) t -> ('a, 'b) t2
-
-val zip_i : 'a t -> (int, 'a) t2
- (** Zip elements of the sequence with their index in the sequence *)
-
-val fold2 : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t2 -> 'c
-
-val iter2 : ('a -> 'b -> unit) -> ('a, 'b) t2 -> unit
-
-val map2 : ('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t
-
-val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a, 'b) t2 -> ('c, 'd) t2
- (** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
-
-(** {2 Basic data structures converters} *)
-
-val to_list : 'a t -> 'a list
- (** Convert the sequence into a list. Preserves order of elements.
- This function is tail-recursive, but consumes 2*n memory.
- If order doesn't matter to you, consider {!to_rev_list}. *)
-
-val to_rev_list : 'a t -> 'a list
- (** Get the list of the reversed sequence (more efficient than {!to_list}) *)
-
-val of_list : 'a list -> 'a t
-
-val on_list : ('a t -> 'b t) -> 'a list -> 'b list
-(** [on_list f l] is equivalent to [to_list @@ f @@ of_list l].
- @since 0.3.4
-*)
-
-val to_opt : 'a t -> 'a option
- (** Alias to {!head}
- @since 0.3.4 *)
-
-val to_array : 'a t -> 'a array
- (** Convert to an array. Currently not very efficient because
- an intermediate list is used. *)
-
-val of_array : 'a array -> 'a t
-
-val of_array_i : 'a array -> (int * 'a) t
- (** Elements of the array, with their index *)
-
-val of_array2 : 'a array -> (int, 'a) t2
-
-val array_slice : 'a array -> int -> int -> 'a t
- (** [array_slice a i j] Sequence of elements whose indexes range
- from [i] to [j] *)
-
-val of_opt : 'a option -> 'a t
- (** Iterate on 0 or 1 values.
- @since 0.3.4 *)
-
-val of_stream : 'a Stream.t -> 'a t
- (** Sequence of elements of a stream (usable only once) *)
-
-val to_stream : 'a t -> 'a Stream.t
- (** Convert to a stream. linear in memory and time (a copy is made in memory) *)
-
-val to_stack : 'a Stack.t -> 'a t -> unit
- (** Push elements of the sequence on the stack *)
-
-val of_stack : 'a Stack.t -> 'a t
- (** Sequence of elements of the stack (same order as [Stack.iter]) *)
-
-val to_queue : 'a Queue.t -> 'a t -> unit
- (** Push elements of the sequence into the queue *)
-
-val of_queue : 'a Queue.t -> 'a t
- (** Sequence of elements contained in the queue, FIFO order *)
-
-val hashtbl_add : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
- (** Add elements of the sequence to the hashtable, with
- Hashtbl.add *)
-
-val hashtbl_replace : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
- (** Add elements of the sequence to the hashtable, with
- Hashtbl.replace (erases conflicting bindings) *)
-
-val to_hashtbl : ('a * 'b) t -> ('a, 'b) Hashtbl.t
- (** Build a hashtable from a sequence of key/value pairs *)
-
-val to_hashtbl2 : ('a, 'b) t2 -> ('a, 'b) Hashtbl.t
- (** Build a hashtable from a sequence of key/value pairs *)
-
-val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b) t
- (** Sequence of key/value pairs from the hashtable *)
-
-val of_hashtbl2 : ('a, 'b) Hashtbl.t -> ('a, 'b) t2
- (** Sequence of key/value pairs from the hashtable *)
-
-val hashtbl_keys : ('a, 'b) Hashtbl.t -> 'a t
-val hashtbl_values : ('a, 'b) Hashtbl.t -> 'b t
-
-val of_str : string -> char t
-val to_str : char t -> string
-
-val concat_str : string t -> string
- (** Concatenate strings together, eagerly.
- Also see {!intersperse} to add a separator.
- @since 0.3.4 *)
-
-exception OneShotSequence
- (** Raised when the user tries to iterate several times on
- a transient iterator *)
-
-val of_in_channel : in_channel -> char t
- (** Iterates on characters of the input (can block when one
- iterates over the sequence). If you need to iterate
- several times on this sequence, use {!persistent}.
- @raise OneShotSequence when used more than once. *)
-
-val to_buffer : char t -> Buffer.t -> unit
- (** Copy content of the sequence into the buffer *)
-
-val int_range : start:int -> stop:int -> int t
- (** Iterator on integers in [start...stop] by steps 1. Also see
- {!(--)} for an infix version. *)
-
-val int_range_dec : start:int -> stop:int -> int t
- (** Iterator on decreasing integers in [stop...start] by steps -1.
- See {!(--^)} for an infix version *)
-
-val of_set : (module Set.S with type elt = 'a and type t = 'b) -> 'b -> 'a t
- (** Convert the given set to a sequence. The set module must be provided. *)
-
-val to_set : (module Set.S with type elt = 'a and type t = 'b) -> 'a t -> 'b
- (** Convert the sequence to a set, given the proper set module *)
-
-type 'a gen = unit -> 'a option
-type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
-
-val of_gen : 'a gen -> 'a t
- (** Traverse eagerly the generator and build a sequence from it *)
-
-val to_gen : 'a t -> 'a gen
- (** Make the sequence persistent (O(n)) and then iterate on it. Eager. *)
-
-val of_klist : 'a klist -> 'a t
- (** Iterate on the lazy list *)
-
-val to_klist : 'a t -> 'a klist
- (** Make the sequence persistent and then iterate on it. Eager. *)
-
-(** {2 Functorial conversions between sets and sequences} *)
-
-module Set : sig
- module type S = sig
- include Set.S
- val of_seq : elt sequence -> t
- val to_seq : t -> elt sequence
-
- val to_list : t -> elt list
- (** @since 0.3.4 *)
-
- val of_list : elt list -> t
- (** @since 0.3.4 *)
- end
-
- (** Create an enriched Set module from the given one *)
- module Adapt(X : Set.S) : S with type elt = X.elt and type t = X.t
-
- (** Functor to build an extended Set module from an ordered type *)
- module Make(X : Set.OrderedType) : S with type elt = X.t
-end
-
-(** {2 Conversion between maps and sequences.} *)
-
-module Map : sig
- module type S = sig
- include Map.S
- val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : (key * 'a) sequence -> 'a t
- val keys : 'a t -> key sequence
- val values : 'a t -> 'a sequence
-
- val to_list : 'a t -> (key * 'a) list
- (** @since 0.3.4 *)
-
- val of_list : (key * 'a) list -> 'a t
- (** @since 0.3.4 *)
- end
-
- (** Adapt a pre-existing Map module to make it sequence-aware *)
- module Adapt(M : Map.S) : S with type key = M.key and type 'a t = 'a M.t
-
- (** Create an enriched Map module, with sequence-aware functions *)
- module Make(V : Map.OrderedType) : S with type key = V.t
-end
-
-(** {2 Infinite sequences of random values} *)
-
-val random_int : int -> int t
- (** Infinite sequence of random integers between 0 and
- the given higher bound (see Random.int) *)
-
-val random_bool : bool t
- (** Infinite sequence of random bool values *)
-
-val random_float : float -> float t
-
-val random_array : 'a array -> 'a t
- (** Sequence of choices of an element in the array *)
-
-val random_list : 'a list -> 'a t
- (** Infinite sequence of random elements of the list. Basically the
- same as {!random_array}. *)
-
-(** {2 Infix functions} *)
-
-module Infix : sig
- val (--) : int -> int -> int t
- (** [a -- b] is the range of integers from [a] to [b], both included,
- in increasing order. It will therefore be empty if [a > b]. *)
-
- val (--^) : int -> int -> int t
- (** [a --^ b] is the range of integers from [b] to [a], both included,
- in decreasing order (starts from [a]).
- It will therefore be empty if [a < b]. *)
-
- val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
- (** Monadic bind (infix version of {!flat_map}
- @since 0.3.4 *)
-
- val (>|=) : 'a t -> ('a -> 'b) -> 'b t
- (** Infix version of {!map}
- @since 0.3.4 *)
-
- val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
- (** Applicative operator (product+application)
- @since 0.3.4 *)
-
- val (<+>) : 'a t -> 'a t -> 'a t
- (** Concatenation of sequences
- @since 0.3.4 *)
-end
-
-include module type of Infix
-
-
-(** {2 Pretty printing of sequences} *)
-
-val pp_seq : ?sep:string -> (Format.formatter -> 'a -> unit) ->
- Format.formatter -> 'a t -> unit
- (** Pretty print a sequence of ['a], using the given pretty printer
- to print each elements. An optional separator string can be provided. *)
-
-val pp_buf : ?sep:string -> (Buffer.t -> 'a -> unit) ->
- Buffer.t -> 'a t -> unit
- (** Print into a buffer *)
-
-val to_string : ?sep:string -> ('a -> string) -> 'a t -> string
- (** Print into a string *)
-
-(** {2 Basic IO}
-
-Very basic interface to manipulate files as sequence of chunks/lines. The
-sequences take care of opening and closing files properly; every time
-one iterates over a sequence, the file is opened/closed again.
-
-Example: copy a file ["a"] into file ["b"], removing blank lines:
-
-{[
- Sequence.(IO.lines_of "a" |> filter (fun l-> l<> "") |> IO.write_lines "b");;
-]}
-
-By chunks of [4096] bytes:
-
-{[
- Sequence.IO.(chunks_of ~size:4096 "a" |> write_to "b");;
-]}
-
-Read the lines of a file into a list:
-
-{[
- Sequence.IO.lines "a" |> Sequence.to_list
-]}
-
-@since 0.3.4 *)
-
-module IO : sig
- val lines_of : ?mode:int -> ?flags:open_flag list ->
- string -> string t
- (** [lines_of filename] reads all lines of the given file. It raises the
- same exception as would opening the file and read from it, except
- from [End_of_file] (which is caught). The file is {b always} properly
- closed.
- Every time the sequence is iterated on, the file is opened again, so
- different iterations might return different results
- @param mode default [0o644]
- @param flags default: [[Open_rdonly]] *)
-
- val chunks_of : ?mode:int -> ?flags:open_flag list -> ?size:int ->
- string -> string t
- (** Read chunks of the given [size] from the file. The last chunk might be
- smaller. Behaves like {!lines_of} regarding errors and options.
- Every time the sequence is iterated on, the file is opened again, so
- different iterations might return different results *)
-
- val write_to : ?mode:int -> ?flags:open_flag list ->
- string -> string t -> unit
- (** [write_to filename seq] writes all strings from [seq] into the given
- file. It takes care of opening and closing the file.
- @param mode default [0o644]
- @param flags used by [open_out_gen]. Default: [[Open_creat;Open_wronly]]. *)
-
- val write_bytes_to : ?mode:int -> ?flags:open_flag list ->
- string -> Bytes.t t -> unit
- (** @since 0.5 *)
-
- val write_lines : ?mode:int -> ?flags:open_flag list ->
- string -> string t -> unit
- (** Same as {!write_to}, but intercales ['\n'] between each string *)
-
- val write_bytes_lines : ?mode:int -> ?flags:open_flag list ->
- string -> Bytes.t t -> unit
- (** @since 0.5 *)
-end
diff --git a/core/Gen_intf.ml b/core/Gen_intf.ml
deleted file mode 120000
index 32cbb5c8..00000000
--- a/core/Gen_intf.ml
+++ /dev/null
@@ -1 +0,0 @@
-../gen/gen_intf.ml
\ No newline at end of file
diff --git a/doc/build_deps.ml b/doc/build_deps.ml
new file mode 100755
index 00000000..5386c641
--- /dev/null
+++ b/doc/build_deps.ml
@@ -0,0 +1,26 @@
+#!/usr/bin/env ocaml
+
+#use "topfind";;
+#require "containers";;
+#require "containers.io";;
+#require "gen";;
+#require "unix";;
+
+let odoc_files =
+ CCIO.File.walk "_build"
+ |> Gen.filter_map
+ (function
+ | `File, f when CCString.suffix ~suf:".odoc" f -> Some f
+ | _ -> None
+ )
+ |> Gen.flat_map
+ (fun f -> Gen.of_list ["-load"; f])
+ |> Gen.to_list
+;;
+
+let cmd =
+ "ocamldoc -dot -o deps.dot " ^ String.concat " " odoc_files
+;;
+
+print_endline ("run: " ^ cmd);;
+Unix.system cmd;;
diff --git a/doc/intro.txt b/doc/intro.txt
new file mode 100644
index 00000000..afde017d
--- /dev/null
+++ b/doc/intro.txt
@@ -0,0 +1,137 @@
+{1 Containers}
+
+{2 Change Log}
+
+See {{: https://github.com/c-cube/ocaml-containers/blob/master/CHANGELOG.md } this file}
+
+{2 License}
+
+This code is free, under the BSD license.
+
+The logo (media/logo.png) is
+CC-SA3 {{:http://en.wikipedia.org/wiki/File:Hypercube.svg} wikimedia}
+
+{2 Contents}
+
+The design is mostly centered around polymorphism rather than functors. Such
+structures comprise (some modules in misc/, some other in core/):
+
+the core library, containers, now depends on
+{{:https://github.com/mjambon/cppo}cppo} and base-bytes (provided
+by ocamlfind).
+
+{4 Core Modules (extension of the standard library)}
+
+{!modules:
+CCArray
+CCBool
+CCError
+CCFloat
+CCFun
+CCHash
+CCHeap
+CCInt
+CCList
+CCOpt
+CCOrd
+CCPair
+CCPrint
+CCRandom
+CCString
+CCVector
+}
+
+{4 Pervasives (aliases to Core Modules)}
+
+Contains aliases to most modules from {i containers core}, and mixins
+such as:
+
+{[ module List = struct
+ include List
+ include CCList
+ end
+]}
+
+{!modules: CCPervasives}
+
+{4 Containers.data}
+
+Various data structures.
+
+{!modules:
+CCBV
+CCCache
+CCFQueue
+CCFlatHashtbl
+CCMixtbl
+CCMultiMap
+CCMultiSet
+CCPersistentHashtbl
+CCTrie
+}
+
+{4 Containers.io}
+
+Helpers to perform simple IO (mostly on files) and iterate on channels.
+
+{!modules: CCIO}
+
+{4 Containers.sexp}
+
+A small S-expression library. The interface is relatively unstable, but
+the main type ([CCSexp.t]) isn't.
+
+{!modules: CCSexp CCSexpStream CCSexpM}
+
+{4 Containers.iter}
+
+Iterators:
+
+{!modules: CCKList CCKTree}
+
+{4 String}
+
+{!modules: Levenshtein KMP}
+
+{4 Bigarrays}
+
+Use bigarrays to hold large strings and map files directly into memory.
+
+{!modules: CCBigstring}
+
+{4 Advanced}
+
+This module is qualified with [Containers_advanced].
+
+{!modules: CCLinq CCCat CCBatch}
+
+{4 Misc}
+
+This list is not necessarily up-to-date.
+
+{!modules:
+AbsSet
+Bij
+FlatHashtbl
+Hashset
+Heap
+Heap
+LazyGraph
+PHashtbl
+PrintBox
+RAL
+SmallSet
+SplayMap
+SplayTree
+UnionFind
+Univ
+}
+
+{4 Others}
+
+{!modules: CCFuture}
+
+
+{2 Index}
+
+{!indexlist}
diff --git a/examples/id_sexp.ml b/examples/id_sexp.ml
index a5d73e9b..1adf3080 100644
--- a/examples/id_sexp.ml
+++ b/examples/id_sexp.ml
@@ -3,11 +3,11 @@
let () =
if Array.length Sys.argv <> 2 then failwith "usage: id_sexp file";
let f = Sys.argv.(1) in
- let s = CCSexp.L.of_file f in
+ let s = CCSexpStream.L.of_file f in
match s with
| `Ok l ->
List.iter
- (fun s -> Format.printf "@[%a@]@." CCSexp.print s)
+ (fun s -> Format.printf "@[%a@]@." CCSexpStream.print s)
l
| `Error msg ->
Format.printf "error: %s@." msg
diff --git a/examples/id_sexp2.ml b/examples/id_sexp2.ml
new file mode 100644
index 00000000..90e63c27
--- /dev/null
+++ b/examples/id_sexp2.ml
@@ -0,0 +1,13 @@
+
+
+let () =
+ if Array.length Sys.argv <> 2 then failwith "usage: id_sexp file";
+ let f = Sys.argv.(1) in
+ let s = CCSexpM.parse_file_list f in
+ match s with
+ | `Ok l ->
+ List.iter
+ (fun s -> Format.printf "@[%a@]@." CCSexpM.print s)
+ l
+ | `Error msg ->
+ Format.printf "error: %s@." msg
diff --git a/examples/mem_size.ml b/examples/mem_size.ml
index d424e9ed..4e69c083 100644
--- a/examples/mem_size.ml
+++ b/examples/mem_size.ml
@@ -1,7 +1,7 @@
(** Compute the memory footprint of a value (and its subvalues). Reference is
http://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/ *)
-module Sequence = CCSequence
+
(** A graph vertex is an Obj.t value *)
let graph =
diff --git a/gen/.gitignore b/gen/.gitignore
deleted file mode 100644
index 20f09d16..00000000
--- a/gen/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.*.swp
-.*.swo
-_build
-*.native
-*.byte
-.session
-TAGS
-*.docdir
-setup.log
-setup.data
-qtest
diff --git a/gen/.merlin b/gen/.merlin
deleted file mode 100644
index 26649dfa..00000000
--- a/gen/.merlin
+++ /dev/null
@@ -1,5 +0,0 @@
-S .
-B _build
-S tests
-B _build/tests
-PKG oUnit
diff --git a/gen/META b/gen/META
deleted file mode 100644
index edcf3e82..00000000
--- a/gen/META
+++ /dev/null
@@ -1,11 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: c6b7b0973d898c3e8b7f565b701ee0d0)
-version = "0.2.2"
-description = "Simple, efficient iterators for OCaml"
-archive(byte) = "gen.cma"
-archive(byte, plugin) = "gen.cma"
-archive(native) = "gen.cmxa"
-archive(native, plugin) = "gen.cmxs"
-exists_if = "gen.cma"
-# OASIS_STOP
-
diff --git a/gen/Makefile b/gen/Makefile
deleted file mode 100644
index 43e32bdf..00000000
--- a/gen/Makefile
+++ /dev/null
@@ -1,59 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: a3c674b4239234cbbe53afe090018954)
-
-SETUP = ocaml setup.ml
-
-build: setup.data
- $(SETUP) -build $(BUILDFLAGS)
-
-doc: setup.data build
- $(SETUP) -doc $(DOCFLAGS)
-
-test: setup.data build
- $(SETUP) -test $(TESTFLAGS)
-
-all:
- $(SETUP) -all $(ALLFLAGS)
-
-install: setup.data
- $(SETUP) -install $(INSTALLFLAGS)
-
-uninstall: setup.data
- $(SETUP) -uninstall $(UNINSTALLFLAGS)
-
-reinstall: setup.data
- $(SETUP) -reinstall $(REINSTALLFLAGS)
-
-clean:
- $(SETUP) -clean $(CLEANFLAGS)
-
-distclean:
- $(SETUP) -distclean $(DISTCLEANFLAGS)
-
-setup.data:
- $(SETUP) -configure $(CONFIGUREFLAGS)
-
-configure:
- $(SETUP) -configure $(CONFIGUREFLAGS)
-
-.PHONY: build doc test all install uninstall reinstall clean distclean configure
-
-# OASIS_STOP
-
-push_doc: all doc
- scp -r gen.docdir/* cedeela.fr:~/simon/root/software/gen/
-
-qtest-gen:
- mkdir -p qtest
- qtest extract gen.ml > qtest/run_qtest.ml
-
-test-all:
- ./run_tests.native
- ./run_qtest.native
-
-VERSION=$(shell awk '/^Version:/ {print $$2}' _oasis)
-
-update_next_tag:
- @echo "update version to $(VERSION)..."
- sed -i "s/NEXT_VERSION/$(VERSION)/g" *.ml *.mli
- sed -i "s/NEXT_RELEASE/$(VERSION)/g" *.ml *.mli
diff --git a/gen/README.md b/gen/README.md
deleted file mode 100644
index f8ff67c6..00000000
--- a/gen/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-Gen
-===
-
-Iterators for OCaml, both restartable and consumable. Performances should
-be good, yet the code is simple and straightforward.
-
-The documentation can be found [here](http://cedeela.fr/~simon/software/gen)
-
-## Use
-
-You can either build and install the library (see `Build`), or just copy
-files to your own project. The last solution has the benefits that you
-don't have additional dependencies nor build complications (and it may enable
-more inlining). I therefore recommand it for its simplicity.
-
-If you have comments, requests, or bugfixes, please share them! :-)
-
-## Build
-
-There are no dependencies. This should work with OCaml>=3.12.
-
- $ make
-
-To build and run tests (requires `oUnit`):
-
- $ opam install oUnit
- $ make tests
- $ ./tests.native
-
-## License
-
-This code is free, under the BSD license.
diff --git a/gen/_oasis b/gen/_oasis
deleted file mode 100644
index d13b7765..00000000
--- a/gen/_oasis
+++ /dev/null
@@ -1,65 +0,0 @@
-OASISFormat: 0.3
-Name: gen
-Version: 0.2.2
-Homepage: https://github.com/c-cube/gen
-Authors: Simon Cruanes
-License: BSD3
-LicenseFile: LICENSE
-Plugins: META (0.3), DevFiles (0.3)
-BuildTools: ocamlbuild
-
-Synopsis: Simple, efficient iterators for OCaml
-
-Flag "bench"
- Description: build benchmark
- Default: false
-
-Library "gen"
- Path: .
- Pack: false
- Modules: Gen, Gen_intf
-
-Document gen
- Title: Containers docs
- Type: ocamlbuild (0.3)
- BuildTools+: ocamldoc
- Install: true
- XOCamlbuildPath: .
- XOCamlbuildLibraries: gen
-
-PreBuildCommand: make qtest-gen
-
-Executable run_tests
- Path: tests/
- Install: false
- CompiledObject: native
- MainIs: run_tests.ml
- Build$: flag(tests)
- BuildDepends: gen,oUnit
-
-Executable run_qtest
- Path: qtest/
- Install: false
- CompiledObject: native
- MainIs: run_qtest.ml
- Build$: flag(tests)
- BuildDepends: containers, containers.misc, containers.string,
- oUnit, QTest2Lib
-
-Test all
- Command: make test-all
- TestTools: run_tests, run_qtest
- Run$: flag(tests)
-
-Executable bench_persistent
- Path: bench/
- Install: false
- CompiledObject: native
- MainIs: bench_persistent.ml
- Build$: flag(bench)
- BuildDepends: gen,benchmark
-
-SourceRepository head
- Type: git
- Location: https://github.com/c-cube/gen
- Browser: https://github.com/c-cube/gen/tree/master/src
diff --git a/gen/_tags b/gen/_tags
deleted file mode 100644
index 8760f650..00000000
--- a/gen/_tags
+++ /dev/null
@@ -1,43 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: a9f4ed4316e4221c9e3cad121ae7a8a9)
-# Ignore VCS directories, you can use the same kind of rule outside
-# OASIS_START/STOP if you want to exclude directories that contains
-# useless stuff for the build process
-true: annot, bin_annot
-<**/.svn>: -traverse
-<**/.svn>: not_hygienic
-".bzr": -traverse
-".bzr": not_hygienic
-".hg": -traverse
-".hg": not_hygienic
-".git": -traverse
-".git": not_hygienic
-"_darcs": -traverse
-"_darcs": not_hygienic
-# Library gen
-"gen.cmxs": use_gen
-# Executable run_tests
-"tests/run_tests.native": pkg_oUnit
-"tests/run_tests.native": use_gen
-: pkg_oUnit
-: use_gen
-# Executable run_qtest
-"qtest/run_qtest.native": pkg_QTest2Lib
-"qtest/run_qtest.native": pkg_containers
-"qtest/run_qtest.native": pkg_containers.misc
-"qtest/run_qtest.native": pkg_containers.string
-"qtest/run_qtest.native": pkg_oUnit
-: pkg_QTest2Lib
-: pkg_containers
-: pkg_containers.misc
-: pkg_containers.string
-: pkg_oUnit
-# Executable bench_persistent
-"bench/bench_persistent.native": pkg_benchmark
-"bench/bench_persistent.native": use_gen
-: pkg_benchmark
-: use_gen
-# OASIS_STOP
-"qtest": include
-<**/*.ml>: warn_A, warn(-4), warn(-44)
-
diff --git a/gen/bench/.merlin b/gen/bench/.merlin
deleted file mode 100644
index ba79d719..00000000
--- a/gen/bench/.merlin
+++ /dev/null
@@ -1,4 +0,0 @@
-S .
-B ../_build/bench/
-REC
-PKG benchmark
diff --git a/gen/bench/bench_persistent.ml b/gen/bench/bench_persistent.ml
deleted file mode 100644
index d2a5551b..00000000
--- a/gen/bench/bench_persistent.ml
+++ /dev/null
@@ -1,161 +0,0 @@
-
-let _sum g =
- Gen.Restart.fold (+) 0 g
-
-
-module MList = struct
- type 'a t = 'a node option ref
- and 'a node = {
- content : 'a;
- mutable prev : 'a node;
- mutable next : 'a node;
- }
-
- let create () = ref None
-
- let is_empty d =
- match !d with
- | None -> true
- | Some _ -> false
-
- let push_back d x =
- match !d with
- | None ->
- let rec elt = {
- content = x; prev = elt; next = elt; } in
- d := Some elt
- | Some first ->
- let elt = { content = x; next=first; prev=first.prev; } in
- first.prev.next <- elt;
- first.prev <- elt
-
- (* conversion to gen *)
- let to_gen d =
- fun () ->
- match !d with
- | None -> (fun () -> None)
- | Some first ->
- let cur = ref first in (* current element of the list *)
- let stop = ref false in (* are we done yet? *)
- fun () ->
- if !stop then None
- else begin
- let x = (!cur).content in
- cur := (!cur).next;
- (if !cur == first then stop := true); (* EOG, we made a full cycle *)
- Some x
- end
-end
-
-(** Store content of the generator in an enum *)
-let persistent_mlist gen =
- let l = MList.create () in
- Gen.iter (MList.push_back l) gen;
- MList.to_gen l
-
-let bench_mlist n =
- for _i = 0 to 100 do
- let g = persistent_mlist Gen.(1 -- n) in
- ignore (_sum g)
- done
-
-(** {6 Unrolled mutable list} *)
-module UnrolledList = struct
- type 'a node =
- | Nil
- | Partial of 'a array * int
- | Cons of 'a array * 'a node ref
-
- let of_gen gen =
- let start = ref Nil in
- let chunk_size = ref 16 in
- let rec fill prev cur =
- match cur, gen() with
- | Partial (a,n), None ->
- prev := Cons (Array.sub a 0 n, ref Nil); () (* done *)
- | _, None -> prev := cur; () (* done *)
- | Nil, Some x ->
- let n = !chunk_size in
- if n < 4096 then chunk_size := 2 * !chunk_size;
- fill prev (Partial (Array.make n x, 1))
- | Partial (a, n), Some x ->
- assert (n < Array.length a);
- a.(n) <- x;
- if n+1 = Array.length a
- then begin
- let r = ref Nil in
- prev := Cons(a, r);
- fill r Nil
- end else fill prev (Partial (a, n+1))
- | Cons _, _ -> assert false
- in
- fill start !start ;
- !start
-
- let to_gen l () =
- let cur = ref l in
- let i = ref 0 in
- let rec next() = match !cur with
- | Nil -> None
- | Cons (a,l') ->
- if !i = Array.length a
- then begin
- cur := !l';
- i := 0;
- next()
- end else begin
- let y = a.(!i) in
- incr i;
- Some y
- end
- | Partial _ -> assert false
- in
- next
-end
-
-(** Store content of the generator in an enum *)
-let persistent_unrolled gen =
- let l = UnrolledList.of_gen gen in
- UnrolledList.to_gen l
-
-let bench_unrolled n =
- for _i = 0 to 100 do
- let g = persistent_unrolled Gen.(1 -- n) in
- ignore (_sum g)
- done
-
-let bench_naive n =
- for _i = 0 to 100 do
- let l = Gen.to_rev_list Gen.(1 -- n) in
- let g = Gen.Restart.of_list (List.rev l) in
- ignore (_sum g)
- done
-
-let bench_current n =
- for _i = 0 to 100 do
- let g = Gen.persistent Gen.(1 -- n) in
- ignore (_sum g)
- done
-
-let bench_current_lazy n =
- for _i = 0 to 100 do
- let g = Gen.persistent_lazy Gen.(1 -- n) in
- ignore (_sum g)
- done
-
-let () =
- let bench_n n =
- Printf.printf "BENCH for %d\n" n;
- let res = Benchmark.throughputN 5
- [ "mlist", bench_mlist, n
- ; "naive", bench_naive, n
- ; "unrolled", bench_unrolled, n
- ; "current", bench_current, n
- ; "current_lazy", bench_current_lazy, n
- ]
- in Benchmark.tabulate res
- in
- bench_n 100;
- bench_n 100_000;
- ()
-
diff --git a/gen/configure b/gen/configure
deleted file mode 100755
index 6acfaeb9..00000000
--- a/gen/configure
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-# OASIS_START
-# DO NOT EDIT (digest: dc86c2ad450f91ca10c931b6045d0499)
-set -e
-
-FST=true
-for i in "$@"; do
- if $FST; then
- set --
- FST=false
- fi
-
- case $i in
- --*=*)
- ARG=${i%%=*}
- VAL=${i##*=}
- set -- "$@" "$ARG" "$VAL"
- ;;
- *)
- set -- "$@" "$i"
- ;;
- esac
-done
-
-ocaml setup.ml -configure "$@"
-# OASIS_STOP
diff --git a/gen/gen.ml b/gen/gen.ml
deleted file mode 100644
index 8aa35265..00000000
--- a/gen/gen.ml
+++ /dev/null
@@ -1,1669 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Restartable generators} *)
-
-(** {2 Global type declarations} *)
-
-type 'a t = unit -> 'a option
-
-type 'a gen = 'a t
-
-module type S = Gen_intf.S
-
-(** {2 Transient generators} *)
-
-let empty () = None
-
-(*$T empty
- empty |> to_list = []
-*)
-
-let singleton x =
- let first = ref true in
- fun () ->
- if !first then (first := false; Some x) else None
-
-(*T singleton
- singleton 1 |> to_list = [1]
- singleton "foo" |> to_list = ["foo"]
-*)
-
-let repeat x () = Some x
-
-(*$T repeat
- repeat 42 |> take 3 |> to_list = [42; 42; 42]
-*)
-
-let repeatedly f () = Some (f ())
-
-(*$T repeatedly
- repeatedly (let r = ref 0 in fun () -> incr r; !r) \
- |> take 5 |> to_list = [1;2;3;4;5]
-*)
-
-let iterate x f =
- let cur = ref x in
- fun () ->
- let x = !cur in
- cur := f !cur;
- Some x
-
-(*$T iterate
- iterate 0 ((+)1) |> take 5 |> to_list = [0;1;2;3;4]
-*)
-
-let next gen = gen ()
-
-let get gen = gen ()
-
-let get_exn gen =
- match gen () with
- | Some x -> x
- | None -> raise (Invalid_argument "Gen.get_exn")
-
-(*$R get_exn
- let g = of_list [1;2;3] in
- assert_equal 1 (get_exn g);
- assert_equal 2 (get_exn g);
- assert_equal 3 (get_exn g);
- assert_raises (Invalid_argument "Gen.get_exn") (fun () -> get_exn g)
-*)
-
-let junk gen = ignore (gen ())
-
-let rec fold f acc gen =
- match gen () with
- | None -> acc
- | Some x -> fold f (f acc x) gen
-
-(*$Q
- (Q.list Q.small_int) (fun l -> \
- of_list l |> fold (fun l x->x::l) [] = List.rev l)
-*)
-
-let reduce f g =
- let acc = match g () with
- | None -> raise (Invalid_argument "reduce")
- | Some x -> x
- in
- fold f acc g
-
-(* Dual of {!fold}, with a deconstructing operation *)
-let unfold f acc =
- let acc = ref acc in
- fun () ->
- match f !acc with
- | None -> None
- | Some (x, acc') ->
- acc := acc';
- Some x
-
-(*$T unfold
- unfold (fun (prev,cur) -> Some (prev, (cur,prev+cur))) (0,1) \
- |> take 7 |> to_list = [0; 1; 1; 2; 3; 5; 8]
-*)
-
-let init ?(limit=max_int) f =
- let r = ref 0 in
- fun () ->
- if !r >= limit
- then None
- else
- let x = f !r in
- let _ = incr r in
- Some x
-
-(*$T init
- init ~limit:5 (fun i->i) |> to_list = [0;1;2;3;4]
-*)
-
-let rec iter f gen =
- match gen() with
- | None -> ()
- | Some x -> f x; iter f gen
-
-let iteri f gen =
- let rec iteri i = match gen() with
- | None -> ()
- | Some x -> f i x; iteri (i+1)
- in
- iteri 0
-
-let is_empty gen = match gen () with
- | None -> true
- | Some _ -> false
-
-(*$T
- is_empty empty
- not (is_empty (singleton 2))
-*)
-
-let length gen =
- fold (fun acc _ -> acc + 1) 0 gen
-
-(*$Q
- (Q.list Q.small_int) (fun l -> \
- of_list l |> length = List.length l)
-*)
-
-(* useful state *)
-module RunState = struct
- type 'a t =
- | Init
- | Run of 'a
- | Stop
-end
-
-let scan f acc g =
- let open RunState in
- let state = ref Init in
- fun () ->
- match !state with
- | Init ->
- state := Run acc;
- Some acc
- | Stop -> None
- | Run acc ->
- match g() with
- | None -> state := Stop; None
- | Some x ->
- let acc' = f acc x in
- state := Run acc';
- Some acc'
-
-(*$T scan
- scan (fun acc x -> x+1::acc) [] (1--5) |> to_list \
- = [[]; [2]; [3;2]; [4;3;2]; [5;4;3;2]; [6;5;4;3;2]]
-*)
-
-let unfold_scan f acc g =
- let open RunState in
- let state = ref (Run acc) in
- fun () ->
- match !state with
- | Init -> assert false
- | Stop -> None
- | Run acc ->
- match g() with
- | None -> state := Stop; None
- | Some x ->
- let acc', y = f acc x in
- state := Run acc';
- Some y
-
-(*$T unfold_scan
- unfold_scan (fun acc x -> x+acc,acc) 0 (1--5) |> to_list \
- = [0; 1; 3; 6; 10]
-*)
-
-(** {3 Lazy} *)
-
-let map f gen =
- let stop = ref false in
- fun () ->
- if !stop then None
- else match gen() with
- | None -> stop:= true; None
- | Some x -> Some (f x)
-
-(*$Q map
- (Q.list Q.small_int) (fun l -> \
- let f x = x*2 in \
- of_list l |> map f |> to_list = List.map f l)
-*)
-
-let append gen1 gen2 =
- let first = ref true in
- let rec next() =
- if !first
- then match gen1() with
- | (Some _) as x -> x
- | None -> first:=false; next()
- else gen2()
- in next
-
-(*$Q
- (Q.pair (Q.list Q.small_int)(Q.list Q.small_int)) (fun (l1,l2) -> \
- append (of_list l1) (of_list l2) |> to_list = l1 @ l2)
-*)
-
-let flatten next_gen =
- let open RunState in
- let state = ref Init in
- (* get next element *)
- let rec next () =
- match !state with
- | Init -> get_next_gen()
- | Run gen ->
- begin match gen () with
- | None -> get_next_gen ()
- | (Some _) as x -> x
- end
- | Stop -> None
- and get_next_gen() = match next_gen() with
- | None -> state := Stop; None
- | Some gen -> state := Run gen; next()
- in
- next
-
-let flat_map f next_elem =
- let open RunState in
- let state = ref Init in
- let rec next() =
- match !state with
- | Init -> get_next_gen()
- | Run gen ->
- begin match gen () with
- | None -> get_next_gen ()
- | (Some _) as x -> x
- end
- | Stop -> None
- and get_next_gen() = match next_elem() with
- | None -> state:=Stop; None
- | Some x ->
- try state := Run (f x); next()
- with e -> state := Stop; raise e
- in
- next
-
-(*$Q flat_map
- (Q.list Q.small_int) (fun l -> \
- let f x = of_list [x;x*2] in \
- eq (map f (of_list l) |> flatten) (flat_map f (of_list l)))
-*)
-
-let mem ?(eq=(=)) x gen =
- let rec mem eq x gen =
- match gen() with
- | Some y -> eq x y || mem eq x gen
- | None -> false
- in mem eq x gen
-
-let take n gen =
- assert (n >= 0);
- let count = ref 0 in (* how many yielded elements *)
- fun () ->
- if !count = n || !count = ~-1
- then None
- else match gen() with
- | None -> count := ~-1; None (* indicate stop *)
- | (Some _) as x -> incr count; x
-
-(*$Q
- (Q.pair Q.small_int (Q.list Q.small_int)) (fun (n,l) -> \
- of_list l |> take n |> length = Pervasives.min n (List.length l))
-*)
-
-(* call [gen] at most [n] times, and stop *)
-let rec __drop n gen =
- if n = 0 then ()
- else match gen() with
- | Some _ -> __drop (n-1) gen
- | None -> ()
-
-let drop n gen =
- assert (n >= 0);
- let dropped = ref false in
- fun () ->
- if !dropped
- then gen()
- else begin
- (* drop [n] elements and yield the next element *)
- dropped := true;
- __drop n gen;
- gen()
- end
-
-(*$Q
- (Q.pair Q.small_int (Q.list Q.small_int)) (fun (n,l) -> \
- let g1,g2 = take n (of_list l), drop n (of_list l) in \
- append g1 g2 |> to_list = l)
-*)
-
-let nth n gen =
- assert (n>=0);
- __drop n gen;
- match gen () with
- | None -> raise Not_found
- | Some x -> x
-
-(*$= nth & ~printer:string_of_int
- 4 (nth 4 (0--10))
- 8 (nth 8 (0--10))
-*)
-
-(*$T
- (try ignore (nth 11 (1--10)); false with Not_found -> true)
-*)
-
-let take_nth n gen =
- assert (n>=1);
- let i = ref n in
- let rec next() =
- match gen() with
- | None -> None
- | (Some _) as res when !i = n -> i:=1; res
- | Some _ -> incr i; next()
- in next
-
-let filter p gen =
- let rec next () =
- (* wrap exception into option, for next to be tailrec *)
- match gen() with
- | None -> None
- | (Some x) as res ->
- if p x
- then res (* yield element *)
- else next () (* discard element *)
- in next
-
-(*$T
- filter (fun x ->x mod 2 = 0) (1--10) |> to_list = [2;4;6;8;10]
-*)
-
-let take_while p gen =
- let stop = ref false in
- fun () ->
- if !stop
- then None
- else match gen() with
- | (Some x) as res ->
- if p x then res else (stop := true; None)
- | None -> stop:=true; None
-
-(*$T
- take_while (fun x ->x<10) (1--1000) |> eq (1--9)
-*)
-
-module DropWhileState = struct
- type t =
- | Stop
- | Drop
- | Yield
-end
-
-let drop_while p gen =
- let open DropWhileState in
- let state = ref Drop in
- let rec next () =
- match !state with
- | Stop -> None
- | Drop ->
- begin match gen () with
- | None -> state := Stop; None
- | (Some x) as res ->
- if p x then next() else (state:=Yield; res)
- end
- | Yield ->
- begin match gen () with
- | None -> state := Stop; None
- | Some _ as res -> res
- end
- in next
-
-(*$T
- drop_while (fun x-> x<10) (1--20) |> eq (10--20)
-*)
-
-let filter_map f gen =
- (* tailrec *)
- let rec next () =
- match gen() with
- | None -> None
- | Some x ->
- match f x with
- | None -> next()
- | (Some _) as res -> res
- in next
-
-(*$T
- filter_map (fun x-> if x mod 2 = 0 then Some (string_of_int x) else None) (1--10) \
- |> to_list = List.map string_of_int [2;4;6;8;10]
-*)
-
-let zip_index gen =
- let r = ref ~-1 in
- fun () ->
- match gen() with
- | None -> None
- | Some x ->
- incr r;
- Some (!r, x)
-
-(*$T
- zip_index (1--5) |> to_list = [0,1; 1,2; 2,3; 3,4; 4,5]
-*)
-
-let unzip gen =
- let stop = ref false in
- let q1 = Queue.create () in
- let q2 = Queue.create () in
- let next_left () =
- if Queue.is_empty q1
- then if !stop then None
- else match gen() with
- | Some (x,y) ->
- Queue.push y q2;
- Some x
- | None -> stop := true; None
- else Some (Queue.pop q1)
- in
- let next_right () =
- if Queue.is_empty q2
- then if !stop then None
- else match gen() with
- | Some (x,y) ->
- Queue.push x q1;
- Some y
- | None -> stop := true; None
- else Some (Queue.pop q2)
- in
- next_left, next_right
-
-(*$T
- unzip (of_list [1,2;3,4]) |> (fun (x,y)-> to_list x, to_list y) \
- = ([1;3], [2;4])
-*)
-
-(*$Q
- (Q.list (Q.pair Q.small_int Q.small_int)) (fun l -> \
- of_list l |> unzip |> (fun (x,y) -> to_list x,to_list y) = \
- List.split l)
-*)
-
-(* [partition p l] returns the elements that satisfy [p],
- and the elements that do not satisfy [p] *)
-let partition p gen =
- let qtrue = Queue.create () in
- let qfalse = Queue.create () in
- let stop = ref false in
- let rec nexttrue () =
- if Queue.is_empty qtrue
- then if !stop then None
- else match gen() with
- | (Some x) as res ->
- if p x then res else (Queue.push x qfalse; nexttrue())
- | None -> stop:=true; None
- else Some (Queue.pop qtrue)
- and nextfalse() =
- if Queue.is_empty qfalse
- then if !stop then None
- else match gen() with
- | (Some x) as res ->
- if p x then (Queue.push x qtrue; nextfalse()) else res
- | None -> stop:= true; None
- else Some (Queue.pop qfalse)
- in
- nexttrue, nextfalse
-
-(*$T
- partition (fun x -> x mod 2 = 0) (1--10) |> \
- (fun (x,y)->to_list x, to_list y) = ([2;4;6;8;10], [1;3;5;7;9])
-*)
-
-let rec for_all p gen =
- match gen() with
- | None -> true
- | Some x -> p x && for_all p gen
-
-let rec exists p gen =
- match gen() with
- | None -> false
- | Some x -> p x || exists p gen
-
-let min ?(lt=fun x y -> x < y) gen =
- let first = match gen () with
- | Some x -> x
- | None -> raise (Invalid_argument "min")
- in
- fold (fun min x -> if lt x min then x else min) first gen
-
-(*$T
- min (of_list [1;4;6;0;11; -2]) = ~-2
- (try ignore (min empty); false with Invalid_argument _ -> true)
-*)
-
-let max ?(lt=fun x y -> x < y) gen =
- let first = match gen () with
- | Some x -> x
- | None -> raise (Invalid_argument "max")
- in
- fold (fun max x -> if lt max x then x else max) first gen
-
-(*$T
- max (of_list [1;4;6;0;11; -2]) = 11
- (try ignore (max empty); false with Invalid_argument _ -> true)
-*)
-
-let eq ?(eq=(=)) gen1 gen2 =
- let rec check () =
- match gen1(), gen2() with
- | None, None -> true
- | Some x1, Some x2 when eq x1 x2 -> check ()
- | _ -> false
- in
- check ()
-
-(*$Q
- (Q.pair (Q.list Q.small_int)(Q.list Q.small_int)) (fun (l1,l2) -> \
- eq (of_list l1)(of_list l2) = (l1 = l2))
-*)
-
-let lexico ?(cmp=Pervasives.compare) gen1 gen2 =
- let rec lexico () =
- match gen1(), gen2() with
- | None, None -> 0
- | Some x1, Some x2 ->
- let c = cmp x1 x2 in
- if c <> 0 then c else lexico ()
- | Some _, None -> 1
- | None, Some _ -> -1
- in lexico ()
-
-let compare ?cmp gen1 gen2 = lexico ?cmp gen1 gen2
-
-(*$Q
- (Q.pair (Q.list Q.small_int)(Q.list Q.small_int)) (fun (l1,l2) -> \
- let sign x = if x < 0 then -1 else if x=0 then 0 else 1 in \
- sign (compare (of_list l1)(of_list l2)) = sign (Pervasives.compare l1 l2))
-*)
-
-let rec find p e = match e () with
- | None -> None
- | Some x when p x -> Some x
- | Some _ -> find p e
-
-(*$T
- find (fun x -> x>=5) (1--10) = Some 5
- find (fun x -> x>5) (1--4) = None
-*)
-
-let sum e =
- let rec sum acc = match e() with
- | None -> acc
- | Some x -> sum (x+acc)
- in sum 0
-
-(*$T
- sum (1--10) = 55
-*)
-
-(** {2 Multiple Iterators} *)
-
-let map2 f e1 e2 =
- fun () -> match e1(), e2() with
- | Some x, Some y -> Some (f x y)
- | _ -> None
-
-(*$T
- map2 (+) (1--5) (1--4) |> eq (of_list [2;4;6;8])
- map2 (+) (1--5) (repeat 0) |> eq (1--5)
-*)
-
-let rec iter2 f e1 e2 =
- match e1(), e2() with
- | Some x, Some y -> f x y; iter2 f e1 e2
- | _ -> ()
-
-(*$T iter2
- let r = ref 0 in iter2 (fun _ _ -> incr r) (1--10) (4--6); !r = 3
-*)
-
-let rec fold2 f acc e1 e2 =
- match e1(), e2() with
- | Some x, Some y -> fold2 f (f acc x y) e1 e2
- | _ -> acc
-
-let rec for_all2 p e1 e2 =
- match e1(), e2() with
- | Some x, Some y -> p x y && for_all2 p e1 e2
- | _ -> true
-
-let rec exists2 p e1 e2 =
- match e1(), e2() with
- | Some x, Some y -> p x y || exists2 p e1 e2
- | _ -> false
-
-let zip_with f a b =
- let stop = ref false in
- fun () ->
- if !stop then None
- else match a(), b() with
- | Some xa, Some xb -> Some (f xa xb)
- | _ -> stop:=true; None
-
-let zip a b = zip_with (fun x y -> x,y) a b
-
-(*$Q
- (Q.list Q.small_int) (fun l -> \
- zip_with (fun x y->x,y) (of_list l) (of_list l) \
- |> unzip |> fst |> to_list = l)
-*)
-
-(** {3 Complex combinators} *)
-
-module MergeState = struct
- type 'a t = {
- gens : 'a gen Queue.t;
- mutable state : my_state;
- }
-
- and my_state =
- | NewGen
- | YieldAndNew
- | Yield
- | Stop
-end
-
-(* state machine:
- (NewGen -> YieldAndNew)* // then no more generators in next_gen, so
- -> Yield* -> Stop *)
-let merge next_gen =
- let open MergeState in
- let state = {gens = Queue.create(); state=NewGen;}in
- (* recursive function to get next element *)
- let rec next () =
- match state.state with
- | Stop -> None
- | Yield -> (* only yield from generators in state.gens *)
- if Queue.is_empty state.gens
- then (state.state <- Stop; None)
- else
- let gen = Queue.pop state.gens in
- begin match gen () with
- | None -> next()
- | (Some _) as res ->
- Queue.push gen state.gens; (* put gen back in queue *)
- res
- end
- | NewGen ->
- begin match next_gen() with
- | None ->
- state.state <- Yield; (* exhausted *)
- next()
- | Some gen ->
- Queue.push gen state.gens;
- state.state <- YieldAndNew;
- next()
- end
- | YieldAndNew -> (* yield element from queue, then get a new generator *)
- if Queue.is_empty state.gens
- then (state.state <- NewGen; next())
- else
- let gen = Queue.pop state.gens in
- begin match gen () with
- | None -> state.state <- NewGen; next()
- | (Some _) as res ->
- Queue.push gen state.gens;
- state.state <- NewGen;
- res
- end
- in next
-
-(*$T
- merge (of_list [of_list [1;3;5]; of_list [2;4;6]; of_list [7;8;9]]) \
- |> to_list |> List.sort Pervasives.compare = [1;2;3;4;5;6;7;8;9]
-*)
-
-let intersection ?(cmp=Pervasives.compare) gen1 gen2 =
- let x1 = ref (gen1 ()) in
- let x2 = ref (gen2 ()) in
- let rec next () =
- match !x1, !x2 with
- | Some y1, Some y2 ->
- let c = cmp y1 y2 in
- if c = 0 (* equal elements, yield! *)
- then (x1 := gen1(); x2 := gen2(); Some y1)
- else if c < 0 (* drop y1 *)
- then (x1 := gen1 (); next ())
- else (* drop y2 *)
- (x2 := gen2(); next ())
- | _ -> None
- in next
-
-(*$T
- intersection (of_list [1;1;2;3;4;8]) (of_list [1;2;4;5;6;7;8;9]) \
- |> to_list = [1;2;4;8]
-*)
-
-let sorted_merge ?(cmp=Pervasives.compare) gen1 gen2 =
- let x1 = ref (gen1 ()) in
- let x2 = ref (gen2 ()) in
- fun () ->
- match !x1, !x2 with
- | None, None -> None
- | (Some y1)as r1, ((Some y2) as r2) ->
- if cmp y1 y2 <= 0
- then (x1 := gen1 (); r1)
- else (x2 := gen2 (); r2)
- | (Some _)as r, None ->
- x1 := gen1 ();
- r
- | None, ((Some _)as r) ->
- x2 := gen2 ();
- r
-
-(*$T
- sorted_merge (of_list [1;2;2;3;5;10;100]) (of_list [2;4;5;6;11]) \
- |> to_list = [1;2;2;2;3;4;5;5;6;10;11;100]
-*)
-
-(** {4 Mutable heap (taken from heap.ml to avoid dependencies)} *)
-module Heap = struct
- type 'a t = {
- mutable tree : 'a tree;
- cmp : 'a -> 'a -> int;
- } (** A pairing tree heap with the given comparison function *)
- and 'a tree =
- | Empty
- | Node of 'a * 'a tree * 'a tree
-
- let empty ~cmp = {
- tree = Empty;
- cmp;
- }
-
- let is_empty h =
- match h.tree with
- | Empty -> true
- | Node _ -> false
-
- let rec union ~cmp t1 t2 = match t1, t2 with
- | Empty, _ -> t2
- | _, Empty -> t1
- | Node (x1, l1, r1), Node (x2, l2, r2) ->
- if cmp x1 x2 <= 0
- then Node (x1, union ~cmp t2 r1, l1)
- else Node (x2, union ~cmp t1 r2, l2)
-
- let insert h x =
- h.tree <- union ~cmp:h.cmp (Node (x, Empty, Empty)) h.tree
-
- let pop h = match h.tree with
- | Empty -> raise Not_found
- | Node (x, l, r) ->
- h.tree <- union ~cmp:h.cmp l r;
- x
-end
-
-let sorted_merge_n ?(cmp=Pervasives.compare) l =
- (* make a heap of (value, generator) *)
- let cmp (v1,_) (v2,_) = cmp v1 v2 in
- let heap = Heap.empty ~cmp in
- (* add initial values *)
- List.iter
- (fun gen' -> match gen'() with
- | Some x -> Heap.insert heap (x, gen')
- | None -> ())
- l;
- fun () ->
- if Heap.is_empty heap then None
- else begin
- let x, gen = Heap.pop heap in
- match gen() with
- | Some y ->
- Heap.insert heap (y, gen); (* insert next value *)
- Some x
- | None -> Some x (* gen empty, drop it *)
- end
-
-(*$T
- sorted_merge_n [of_list [1;2;2;3;5;10;100]; of_list [2;4;5;6;11]; (6--10)] \
- |> to_list = [1;2;2;2;3;4;5;5;6;6;7;8;9;10;10;11;100]
-*)
-
-let round_robin ?(n=2) gen =
- (* array of queues, together with their index *)
- let qs = Array.init n (fun _ -> Queue.create ()) in
- let cur = ref 0 in
- (* get next element for the i-th queue *)
- let rec next i =
- let q = qs.(i) in
- if Queue.is_empty q
- then update_to_i i (* consume generator *)
- else Some(Queue.pop q)
- (* consume [gen] until some element for [i]-th generator is
- available. *)
- and update_to_i i =
- match gen() with
- | None -> None
- | Some x ->
- let j = !cur in
- cur := (j+1) mod n; (* move cursor to next generator *)
- let q = qs.(j) in
- if j = i
- then begin
- assert (Queue.is_empty q);
- Some x (* return the element *)
- end else begin
- Queue.push x q;
- update_to_i i (* continue consuming [gen] *)
- end
- in
- (* generators *)
- let l = Array.mapi (fun i _ -> (fun () -> next i)) qs in
- Array.to_list l
-
-(*$T
- round_robin ~n:3 (1--12) |> List.map to_list = \
- [[1;4;7;10]; [2;5;8;11]; [3;6;9;12]]
-*)
-
-(* Duplicate the enum into [n] generators (default 2). The generators
- share the same underlying instance of the enum, so the optimal case is
- when they are consumed evenly *)
-let tee ?(n=2) gen =
- (* array of queues, together with their index *)
- let qs = Array.init n (fun _ -> Queue.create ()) in
- let finished = ref false in (* is [gen] exhausted? *)
- (* get next element for the i-th queue *)
- let rec next i =
- if Queue.is_empty qs.(i)
- then
- if !finished then None
- else get_next i (* consume generator *)
- else Queue.pop qs.(i)
- (* consume one more element *)
- and get_next i = match gen() with
- | Some _ as res ->
- for j = 0 to n-1 do
- if j <> i then Queue.push res qs.(j)
- done;
- res
- | None -> finished := true; None
- in
- (* generators *)
- let l = Array.mapi (fun i _ -> (fun () -> next i)) qs in
- Array.to_list l
-
-(*$T
- tee ~n:3 (1--12) |> List.map to_list = \
- [to_list (1--12); to_list (1--12); to_list (1--12)]
-*)
-
-
-module InterleaveState = struct
- type 'a t =
- | Only of 'a gen
- | Both of 'a gen * 'a gen * bool ref
- | Stop
-end
-
-(* Yield elements from a and b alternatively *)
-let interleave gen_a gen_b =
- let open InterleaveState in
- let state = ref (Both (gen_a, gen_b, ref true)) in
- let rec next() = match !state with
- | Stop -> None
- | Only g ->
- begin match g() with
- | None -> state := Stop; None
- | (Some _) as res -> res
- end
- | Both (g1, g2, r) ->
- match (if !r then g1() else g2()) with
- | None ->
- state := if !r then Only g2 else Only g1;
- next()
- | (Some _) as res ->
- r := not !r; (* swap *)
- res
- in next
-
-(*$T
- interleave (repeat 0) (1--5) |> take 10 |> to_list = \
- [0;1;0;2;0;3;0;4;0;5]
-*)
-
-module IntersperseState = struct
- type 'a t =
- | Start
- | YieldElem of 'a option
- | YieldSep of 'a option (* next val *)
- | Stop
-end
-
-(* Put [x] between elements of [enum] *)
-let intersperse x gen =
- let open IntersperseState in
- let state = ref Start in
- let rec next() = match !state with
- | Stop -> None
- | YieldElem res ->
- begin match gen() with
- | None -> state := Stop
- | Some _ as res' -> state := YieldSep res'
- end;
- res
- | YieldSep res ->
- state := YieldElem res;
- Some x
- | Start ->
- match gen() with
- | None -> state := Stop; None
- | Some _ as res -> state := YieldElem res; next()
- in next
-
-(*$T
- intersperse 0 (1--5) |> to_list = [1;0;2;0;3;0;4;0;5]
-*)
-
-(* Cartesian product *)
-let product gena genb =
- let all_a = ref [] in
- let all_b = ref [] in
- (* cur: current state, i.e., what we have to do next. Can be stop,
- getLeft/getRight (to obtain next element from first/second generator),
- or prodLeft/prodRIght to compute the product of an element with a list
- of already met elements *)
- let cur = ref `GetLeft in
- let rec next () =
- match !cur with
- | `Stop -> None
- | `GetLeft ->
- begin match gena() with
- | None -> cur := `GetRightOrStop
- | Some a -> all_a := a :: !all_a; cur := `ProdLeft (a, !all_b)
- end;
- next ()
- | `GetRight | `GetRightOrStop -> (* TODO: test *)
- begin match genb() with
- | None when !cur = `GetRightOrStop -> cur := `Stop
- | None -> cur := `GetLeft
- | Some b -> all_b := b::!all_b; cur := `ProdRight (b, !all_a)
- end;
- next ()
- | `ProdLeft (_, []) ->
- cur := `GetRight;
- next()
- | `ProdLeft (x, y::l) ->
- cur := `ProdLeft (x, l);
- Some (x, y)
- | `ProdRight (_, []) ->
- cur := `GetLeft;
- next()
- | `ProdRight (y, x::l) ->
- cur := `ProdRight (y, l);
- Some (x, y)
- in
- next
-
-(*$T
- product (1--3) (of_list ["a"; "b"]) |> to_list \
- |> List.sort Pervasives.compare = \
- [1, "a"; 1, "b"; 2, "a"; 2, "b"; 3, "a"; 3, "b"]
-*)
-
-(* Group equal consecutive elements together. *)
-let group ?(eq=(=)) gen =
- match gen() with
- | None -> fun () -> None
- | Some x ->
- let cur = ref [x] in
- let rec next () =
- (* try to get an element *)
- let next_x = if !cur = [] then None else gen() in
- match next_x, !cur with
- | None, [] -> None
- | None, l ->
- cur := []; (* stop *)
- Some l
- | Some x, y::_ when eq x y ->
- cur := x::!cur;
- next () (* same group *)
- | Some x, l ->
- cur := [x];
- Some l
- in next
-
-(*$T
- group (of_list [0;0;0;1;0;2;2;3;4;5;5;5;5;10]) |> to_list = \
- [[0;0;0];[1];[0];[2;2];[3];[4];[5;5;5;5];[10]]
-*)
-
-let uniq ?(eq=(=)) gen =
- let open RunState in
- let state = ref Init in
- let rec next() = match !state with
- | Stop -> None
- | Init ->
- begin match gen() with
- | None -> state:= Stop; None
- | (Some x) as res -> state := Run x; res
- end
- | Run x ->
- begin match gen() with
- | None -> state:= Stop; None
- | (Some y) as res ->
- if eq x y
- then next() (* ignore duplicate *)
- else (state := Run y; res)
- end
- in next
-
-(*$T
- uniq (of_list [0;0;0;1;0;2;2;3;4;5;5;5;5;10]) |> to_list = \
- [0;1;0;2;3;4;5;10]
-*)
-
-let sort ?(cmp=Pervasives.compare) gen =
- (* build heap *)
- let h = Heap.empty ~cmp in
- iter (Heap.insert h) gen;
- fun () ->
- if Heap.is_empty h
- then None
- else Some (Heap.pop h)
-(*$T
- sort (of_list [0;0;0;1;0;2;2;3;4;5;5;5;-42;5;10]) |> to_list = \
- [-42;0;0;0;0;1;2;2;3;4;5;5;5;5;10]
-*)
-
-
-(* NOTE: using a set is not really possible, because once we have built the
- set there is no simple way to iterate on it *)
-let sort_uniq ?(cmp=Pervasives.compare) gen =
- uniq ~eq:(fun x y -> cmp x y = 0) (sort ~cmp gen)
-
-(*$T
- sort_uniq (of_list [0;0;0;1;0;2;2;3;4;5;42;5;5;42;5;10]) |> to_list = \
- [0;1;2;3;4;5;10;42]
-*)
-
-let chunks n e =
- let rec next () =
- match e() with
- | None -> None
- | Some x ->
- let a = Array.make n x in
- fill a 1
-
- and fill a i =
- (* fill the array. [i]: current index to fill *)
- if i = n
- then Some a
- else match e() with
- | None -> Some (Array.sub a 0 i) (* last array is not full *)
- | Some x ->
- a.(i) <- x;
- fill a (i+1)
- in
- next
-
-(*$T
- chunks 25 (0--100) |> map Array.to_list |> to_list = \
- List.map to_list [(0--24); (25--49);(50--74);(75--99);(100--100)]
-*)
-
-(* state of the permutation machine. One machine manages one element [x],
- and depends on a deeper machine [g] that generates permutations of the
- list minus this element (down to the empty list).
- The machine can do two things:
- - insert the element in the current list of [g], at any position
- - obtain the next list of [g]
-*)
-
-module PermState = struct
- type 'a state =
- | Done
- | Base (* bottom machine, yield [] *)
- | Insert of 'a insert_state
- and 'a insert_state = {
- x : 'a;
- mutable l : 'a list;
- mutable n : int; (* idx for insertion *)
- len : int; (* len of [l] *)
- sub : 'a t;
- }
- and 'a t = {
- mutable st : 'a state;
- }
-end
-
-let permutations g =
- let open PermState in
- (* make a machine for n elements. Invariant: n=len(l) *)
- let rec make_machine n l = match l with
- | [] -> assert (n=0); {st=Base}
- | x :: tail ->
- let sub = make_machine (n-1) tail in
- let st = match next sub () with
- | None -> Done
- | Some l -> Insert {x;n=0;l;len=n;sub}
- in
- {st;}
- (* next element of the machine *)
- and next m () = match m.st with
- | Done -> None
- | Base -> m.st <- Done; Some []
- | Insert ({x;len;n;l;sub} as state) ->
- if n=len
- then match next sub () with
- | None -> m.st <- Done; None
- | Some l ->
- state.l <- l;
- state.n <- 0;
- next m ()
- else (
- state.n <- state.n + 1;
- Some (insert x n l)
- )
- and insert x n l = match n, l with
- | 0, _ -> x::l
- | _, [] -> assert false
- | _, y::tail -> y :: insert x (n-1) tail
- in
- let l = fold (fun acc x->x::acc) [] g in
- next (make_machine (List.length l) l)
-
-(*$T permutations
- permutations (1--3) |> to_list |> List.sort Pervasives.compare = \
- [[1;2;3]; [1;3;2]; [2;1;3]; [2;3;1]; [3;1;2]; [3;2;1]]
- permutations empty |> to_list = [[]]
- permutations (singleton 1) |> to_list = [[1]]
-*)
-
-module CombState = struct
- type 'a state =
- | Done
- | Base
- | Add of 'a * 'a t * 'a t (* add x at beginning of first; then switch to second *)
- | Follow of 'a t (* just forward *)
- and 'a t = {
- mutable st : 'a state
- }
-end
-
-let combinations n g =
- let open CombState in
- assert (n >= 0);
- let rec make_state n l = match n, l with
- | 0, _ -> {st=Base}
- | _, [] -> {st=Done}
- | _, x::tail ->
- let m1 = make_state (n-1) tail in
- let m2 = make_state n tail in
- {st=Add(x,m1,m2)}
- and next m () = match m.st with
- | Done -> None
- | Base -> m.st <- Done; Some []
- | Follow m ->
- begin match next m () with
- | None -> m.st <- Done; None
- | Some _ as res -> res
- end
- | Add (x, m1, m2) ->
- match next m1 () with
- | None ->
- m.st <- Follow m2;
- next m ()
- | Some l -> Some (x::l)
- in
- let l = fold (fun acc x->x::acc) [] g in
- next (make_state n l)
-
-(*$T
- combinations 2 (1--4) |> map (List.sort Pervasives.compare) \
- |> to_list |> List.sort Pervasives.compare = \
- [[1;2]; [1;3]; [1;4]; [2;3]; [2;4]; [3;4]]
- combinations 0 (1--4) |> to_list = [[]]
- combinations 1 (singleton 1) |> to_list = [[1]]
-*)
-
-module PowerSetState = struct
- type 'a state =
- | Done
- | Base
- | Add of 'a * 'a t (* add x before any result of m *)
- | AddTo of 'a list * 'a * 'a t (* yield x::list, then back to Add(x,m) *)
- and 'a t = {
- mutable st : 'a state
- }
-end
-
-let power_set g =
- let open PowerSetState in
- let rec make_state l = match l with
- | [] -> {st=Base}
- | x::tail ->
- let m = make_state tail in
- {st=Add(x,m)}
- and next m () = match m.st with
- | Done -> None
- | Base -> m.st <- Done; Some []
- | Add (x,m') ->
- begin match next m' () with
- | None -> m.st <- Done; None
- | Some l as res -> m.st <- AddTo(l,x,m'); res
- end
- | AddTo (l, x, m') ->
- m.st <- Add (x,m');
- Some (x::l)
- in
- let l = fold (fun acc x->x::acc) [] g in
- next (make_state l)
-
-(*$T
- power_set (1--3) |> map (List.sort Pervasives.compare) \
- |> to_list |> List.sort Pervasives.compare = \
- [[]; [1]; [1;2]; [1;2;3]; [1;3]; [2]; [2;3]; [3]]
- power_set empty |> to_list = [[]]
- power_set (singleton 1) |> map (List.sort Pervasives.compare) \
- |> to_list |> List.sort Pervasives.compare = [[]; [1]]
-*)
-
-(** {3 Conversion} *)
-
-let of_list l =
- let l = ref l in
- fun () ->
- match !l with
- | [] -> None
- | x::l' -> l := l'; Some x
-
-let to_rev_list gen =
- fold (fun acc x -> x :: acc) [] gen
-
-(*$Q
- (Q.list Q.small_int) (fun l -> \
- to_rev_list (of_list l) = List.rev l)
-*)
-
-let to_list gen = List.rev (to_rev_list gen)
-
-let to_array gen =
- let l = to_rev_list gen in
- match l with
- | [] -> [| |]
- | _ ->
- let a = Array.of_list l in
- let n = Array.length a in
- (* reverse array *)
- for i = 0 to (n-1) / 2 do
- let tmp = a.(i) in
- a.(i) <- a.(n-i-1);
- a.(n-i-1) <- tmp
- done;
- a
-
-let of_array ?(start=0) ?len a =
- let len = match len with
- | None -> Array.length a - start
- | Some n -> assert (n + start < Array.length a); n in
- let i = ref start in
- fun () ->
- if !i >= start + len
- then None
- else (let x = a.(!i) in incr i; Some x)
-
-(*$Q
- (Q.array Q.small_int) (fun a -> \
- of_array a |> to_array = a)
-*)
-
-let rand_int i =
- repeatedly (fun () -> Random.int i)
-
-let int_range i j =
- let r = ref i in
- fun () ->
- let x = !r in
- if x > j then None
- else begin
- incr r;
- Some x
- end
-
-let pp ?(start="") ?(stop="") ?(sep=",") ?(horizontal=false) pp_elem formatter gen =
- (if horizontal
- then Format.pp_open_hbox formatter ()
- else Format.pp_open_hvbox formatter 0);
- Format.pp_print_string formatter start;
- let rec next is_first =
- match gen() with
- | Some x ->
- if not is_first
- then begin
- Format.pp_print_string formatter sep;
- Format.pp_print_space formatter ();
- pp_elem formatter x
- end else pp_elem formatter x;
- next false
- | None -> ()
- in
- next true;
- Format.pp_print_string formatter stop;
- Format.pp_close_box formatter ()
-
-module Infix = struct
- let (--) = int_range
-
- let (>>=) x f = flat_map f x
-end
-
-include Infix
-
-module Restart = struct
- type 'a t = unit -> 'a gen
-
- type 'a restartable = 'a t
-
- let lift f e = f (e ())
- let lift2 f e1 e2 = f (e1 ()) (e2 ())
-
- let empty () = empty
-
- let singleton x () = singleton x
-
- let iterate x f () = iterate x f
-
- let repeat x () = repeat x
-
- let unfold f acc () = unfold f acc
-
- let init ?limit f () = init ?limit f
-
- let cycle enum =
- assert (not (is_empty (enum ())));
- fun () ->
- let gen = ref (enum ()) in (* start cycle *)
- let rec next () =
- match (!gen) () with
- | (Some _) as res -> res
- | None -> gen := enum(); next()
- in next
-
- let is_empty e = is_empty (e ())
-
- let fold f acc e = fold f acc (e ())
-
- let reduce f e = reduce f (e ())
-
- let scan f acc e () = scan f acc (e ())
-
- let unfold_scan f acc e () = unfold_scan f acc (e())
-
- let iter f e = iter f (e ())
-
- let iteri f e = iteri f (e ())
-
- let length e = length (e ())
-
- let map f e () = map f (e ())
-
- let append e1 e2 () = append (e1 ()) (e2 ())
-
- let flatten e () = flatten (e ())
-
- let flat_map f e () = flat_map f (e ())
-
- let mem ?eq x e = mem ?eq x (e ())
-
- let take n e () = take n (e ())
-
- let drop n e () = drop n (e ())
-
- let nth n e = nth n (e ())
-
- let take_nth n e () = take_nth n (e ())
-
- let filter p e () = filter p (e ())
-
- let take_while p e () = take_while p (e ())
-
- let drop_while p e () = drop_while p (e ())
-
- let filter_map f e () = filter_map f (e ())
-
- let zip_with f e1 e2 () = zip_with f (e1 ()) (e2 ())
-
- let zip e1 e2 () = zip (e1 ()) (e2 ())
-
- let zip_index e () = zip_index (e ())
-
- let unzip e = map fst e, map snd e
-
- let partition p e =
- filter p e, filter (fun x -> not (p x)) e
-
- let for_all p e =
- for_all p (e ())
-
- let exists p e =
- exists p (e ())
-
- let for_all2 p e1 e2 =
- for_all2 p (e1 ()) (e2 ())
-
- let exists2 p e1 e2 =
- exists2 p (e1 ()) (e2 ())
-
- let map2 f e1 e2 () =
- map2 f (e1()) (e2())
-
- let iter2 f e1 e2 =
- iter2 f (e1()) (e2())
-
- let fold2 f acc e1 e2 =
- fold2 f acc (e1()) (e2())
-
- let min ?lt e = min ?lt (e ())
-
- let max ?lt e = max ?lt (e ())
-
- let ___eq = eq
- let eq ?eq e1 e2 = ___eq ?eq (e1 ()) (e2 ())
-
- let lexico ?cmp e1 e2 = lexico ?cmp (e1 ()) (e2 ())
-
- let compare ?cmp e1 e2 = compare ?cmp (e1 ()) (e2 ())
-
- let sum e = sum (e())
-
- let find f e = find f (e())
-
- let merge e () = merge (e ())
-
- let intersection ?cmp e1 e2 () =
- intersection ?cmp (e1 ()) (e2 ())
-
- let sorted_merge ?cmp e1 e2 () =
- sorted_merge ?cmp (e1 ()) (e2 ())
-
- let sorted_merge_n ?cmp l () =
- sorted_merge_n ?cmp (List.map (fun g -> g()) l)
-
- let tee ?n e = tee ?n (e ())
-
- let round_robin ?n e = round_robin ?n (e ())
-
- let interleave e1 e2 () = interleave (e1 ()) (e2 ())
-
- let intersperse x e () = intersperse x (e ())
-
- let product e1 e2 () = product (e1 ()) (e2 ())
-
- let group ?eq e () = group ?eq (e ())
-
- let uniq ?eq e () = uniq ?eq (e ())
-
- let sort ?(cmp=Pervasives.compare) enum =
- fun () -> sort ~cmp (enum ())
-
- let sort_uniq ?(cmp=Pervasives.compare) e =
- let e' = sort ~cmp e in
- uniq ~eq:(fun x y -> cmp x y = 0) e'
-
- let chunks n e () = chunks n (e())
-
- let permutations g () = permutations (g ())
-
- let combinations n g () = combinations n (g())
-
- let power_set g () = power_set (g())
-
- let of_list l () = of_list l
-
- let to_rev_list e = to_rev_list (e ())
-
- let to_list e = to_list (e ())
-
- let to_array e = to_array (e ())
-
- let of_array ?start ?len a () = of_array ?start ?len a
-
- let rand_int i () = rand_int i
-
- let int_range i j () = int_range i j
-
- module Infix = struct
- let (--) = int_range
-
- let (>>=) x f = flat_map f x
- end
-
- include Infix
-
- let pp ?start ?stop ?sep ?horizontal pp_elem fmt e =
- pp ?start ?stop ?sep ?horizontal pp_elem fmt (e ())
-end
-
-(** {2 Generator functions} *)
-
-let start g = g ()
-
-(** {6 Unrolled mutable list} *)
-module MList = struct
- type 'a node =
- | Nil
- | Cons of 'a array * int ref * 'a node ref
- | Suspend of 'a gen
-
- type 'a t = {
- start : 'a node ref; (* first node. *)
- mutable chunk_size : int;
- max_chunk_size : int;
- }
-
- let _make ~max_chunk_size gen = {
- start = ref (Suspend gen);
- chunk_size = 8;
- max_chunk_size;
- }
-
- (* increment the size of chunks *)
- let _incr_chunk_size mlist =
- if mlist.chunk_size < mlist.max_chunk_size
- then mlist.chunk_size <- 2 * mlist.chunk_size
-
- (* read one chunk of input; return the corresponding node.
- will potentially change [mlist.chunk_size]. *)
- let _read_chunk mlist gen =
- match gen() with
- | None -> Nil (* done *)
- | Some x ->
- (* new list node *)
- let r = ref 1 in
- let a = Array.make mlist.chunk_size x in
- let tail = ref (Suspend gen) in
- let stop = ref false in
- let node = Cons (a, r, tail) in
- (* read the rest of the chunk *)
- while not !stop && !r < mlist.chunk_size do
- match gen() with
- | None ->
- tail := Nil;
- stop := true
- | Some x ->
- a.(!r) <- x;
- incr r;
- done;
- _incr_chunk_size mlist;
- node
-
- (* eager construction *)
- let of_gen gen =
- let mlist = _make ~max_chunk_size:4096 gen in
- let rec _fill prev = match _read_chunk mlist gen with
- | Nil -> prev := Nil
- | Suspend _ -> assert false
- | Cons (_, _, prev') as node ->
- prev := node;
- _fill prev'
- in
- _fill mlist.start;
- mlist
-
- (* lazy construction *)
- let of_gen_lazy gen =
- let mlist = _make ~max_chunk_size:32 gen in
- mlist
-
- let to_gen l () =
- let cur = ref l.start in
- let i = ref 0 in
- let rec next() = match ! !cur with
- | Nil -> None
- | Cons (a,n,l') ->
- if !i = !n
- then begin
- cur := l';
- i := 0;
- next()
- end else begin
- let y = a.(!i) in
- incr i;
- Some y
- end
- | Suspend gen ->
- let node = _read_chunk l gen in
- !cur := node;
- next()
- in
- next
-end
-
-(** Store content of the generator in an enum *)
-let persistent gen =
- let l = MList.of_gen gen in
- MList.to_gen l
-
-(*$T
- let g = 1--10 in let g' = persistent g in \
- Restart.to_list g' = Restart.to_list g'
- let g = 1--10 in let g' = persistent g in \
- Restart.to_list g' = [1;2;3;4;5;6;7;8;9;10]
-*)
-
-let persistent_lazy gen =
- let l = MList.of_gen_lazy gen in
- MList.to_gen l
-
-(*$T
- let g = 1--1_000_000_000 in let g' = persistent_lazy g in \
- (g' () |> take 100 |> to_list = (1--100 |> to_list)) && \
- (g' () |> take 200 |> to_list = (1--200 |> to_list))
-*)
diff --git a/gen/gen.mldylib b/gen/gen.mldylib
deleted file mode 100644
index 79105f52..00000000
--- a/gen/gen.mldylib
+++ /dev/null
@@ -1,5 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: f69818d114f140be18d72c90abdc60e8)
-Gen
-Gen_intf
-# OASIS_STOP
diff --git a/gen/gen.mli b/gen/gen.mli
deleted file mode 100644
index 104e19b7..00000000
--- a/gen/gen.mli
+++ /dev/null
@@ -1,102 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Generators}
-
-Values of type ['a Gen.t] represent a possibly infinite sequence of values
-of type 'a. One can only iterate once on the sequence, as it is consumed
-by iteration/deconstruction/access. [None] is returned when the generator
-is exhausted.
-
-The submodule {!Restart} provides utilities to work with
-{b restartable generators}, that is, functions [unit -> 'a Gen.t] that
-allow to build as many generators from the same source as needed.
-*)
-
-(** {2 Global type declarations} *)
-
-type 'a t = unit -> 'a option
- (** A generator may be called several times, yielding the next value
- each time. It returns [None] when no elements remain *)
-
-type 'a gen = 'a t
-
-module type S = Gen_intf.S
-
-(** {2 Transient generators} *)
-
-val get : 'a t -> 'a option
- (** Get the next value *)
-
-val next : 'a t -> 'a option
- (** Synonym for {!get} *)
-
-val get_exn : 'a t -> 'a
- (** Get the next value, or fails
- @raise Invalid_argument if no element remains *)
-
-val junk : 'a t -> unit
- (** Drop the next value, discarding it. *)
-
-val repeatedly : (unit -> 'a) -> 'a t
- (** Call the same function an infinite number of times (useful for instance
- if the function is a random generator). *)
-
-include S with type 'a t := 'a gen
- (** Operations on {b transient} generators *)
-
-(** {2 Restartable generators} *)
-
-module Restart : sig
- type 'a t = unit -> 'a gen
-
- type 'a restartable = 'a t
-
- include S with type 'a t := 'a restartable
-
- val cycle : 'a t -> 'a t
- (** Cycle through the enum, endlessly. The enum must not be empty. *)
-
- val lift : ('a gen -> 'b) -> 'a t -> 'b
-
- val lift2 : ('a gen -> 'b gen -> 'c) -> 'a t -> 'b t -> 'c
-end
-
-(** {2 Utils} *)
-
-val persistent : 'a t -> 'a Restart.t
- (** Store content of the transient generator in memory, to be able to iterate
- on it several times later. If possible, consider using combinators
- from {!Restart} directly instead. *)
-
-val persistent_lazy : 'a t -> 'a Restart.t
- (** Same as {!persistent}, but consumes the generator on demand (by chunks).
- This allows to make a restartable generator out of an ephemeral one,
- without paying a big cost upfront (nor even consuming it fully).
- @since 0.2.2 *)
-
-val start : 'a Restart.t -> 'a t
- (** Create a new transient generator.
- [start gen] is the same as [gen ()] but is included for readability. *)
diff --git a/gen/gen.mllib b/gen/gen.mllib
deleted file mode 100644
index 79105f52..00000000
--- a/gen/gen.mllib
+++ /dev/null
@@ -1,5 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: f69818d114f140be18d72c90abdc60e8)
-Gen
-Gen_intf
-# OASIS_STOP
diff --git a/gen/gen.odocl b/gen/gen.odocl
deleted file mode 100644
index 79105f52..00000000
--- a/gen/gen.odocl
+++ /dev/null
@@ -1,5 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: f69818d114f140be18d72c90abdc60e8)
-Gen
-Gen_intf
-# OASIS_STOP
diff --git a/gen/gen_intf.ml b/gen/gen_intf.ml
deleted file mode 100644
index 87208338..00000000
--- a/gen/gen_intf.ml
+++ /dev/null
@@ -1,321 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Common signature for transient and restartable generators}
-
-The signature {!S} abstracts on a type ['a t], where the [t] can be
-the type of transient or restartable generators. Some functions specify
-explicitely that they use ['a gen] (transient generators). *)
-
-type 'a gen = unit -> 'a option
-
-module type S = sig
- type 'a t
-
- val empty : 'a t
- (** Empty generator, with no elements *)
-
- val singleton : 'a -> 'a t
- (** One-element generator *)
-
- val repeat : 'a -> 'a t
- (** Repeat same element endlessly *)
-
- val iterate : 'a -> ('a -> 'a) -> 'a t
- (** [iterate x f] is [[x; f x; f (f x); f (f (f x)); ...]] *)
-
- val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t
- (** Dual of {!fold}, with a deconstructing operation. It keeps on
- unfolding the ['b] value into a new ['b], and a ['a] which is yielded,
- until [None] is returned. *)
-
- val init : ?limit:int -> (int -> 'a) -> 'a t
- (** Calls the function, starting from 0, on increasing indices.
- If [limit] is provided and is a positive int, iteration will
- stop at the limit (excluded).
- For instance [init ~limit:4 id] will yield 0, 1, 2, and 3. *)
-
- (** {2 Basic combinators} *)
-
- val is_empty : _ t -> bool
- (** Check whether the enum is empty. Pops an element, if any *)
-
- val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
- (** Fold on the generator, tail-recursively. Consumes the generator. *)
-
- val reduce : ('a -> 'a -> 'a) -> 'a t -> 'a
- (** Fold on non-empty sequences. Consumes the generator.
- @raise Invalid_argument on an empty gen *)
-
- val scan : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b t
- (** Like {!fold}, but keeping successive values of the accumulator.
- Consumes the generator. *)
-
- val unfold_scan : ('b -> 'a -> 'b * 'c) -> 'b -> 'a t -> 'c t
- (** A mix of {!unfold} and {!scan}. The current state is combined with
- the current element to produce a new state, and an output value
- of type 'c.
- @since 0.2.2 *)
-
- val iter : ('a -> unit) -> 'a t -> unit
- (** Iterate on the enum, consumes it. *)
-
- val iteri : (int -> 'a -> unit) -> 'a t -> unit
- (** Iterate on elements with their index in the enum, from 0, consuming it. *)
-
- val length : _ t -> int
- (** Length of an enum (linear time), consuming it *)
-
- val map : ('a -> 'b) -> 'a t -> 'b t
- (** Lazy map. No iteration is performed now, the function will be called
- when the result is traversed. *)
-
- val append : 'a t -> 'a t -> 'a t
- (** Append the two enums; the result contains the elements of the first,
- then the elements of the second enum. *)
-
- val flatten : 'a gen t -> 'a t
- (** Flatten the enumeration of generators *)
-
- val flat_map : ('a -> 'b gen) -> 'a t -> 'b t
- (** Monadic bind; each element is transformed to a sub-enum
- which is then iterated on, before the next element is processed,
- and so on. *)
-
- val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
- (** Is the given element, member of the enum? *)
-
- val take : int -> 'a t -> 'a t
- (** Take at most n elements *)
-
- val drop : int -> 'a t -> 'a t
- (** Drop n elements *)
-
- val nth : int -> 'a t -> 'a
- (** n-th element, or Not_found
- @raise Not_found if the generator contains less than [n] arguments *)
-
- val take_nth : int -> 'a t -> 'a t
- (** [take_nth n g] returns every element of [g] whose index
- is a multiple of [n]. For instance [take_nth 2 (1--10) |> to_list]
- will return [1;3;5;7;9] *)
-
- val filter : ('a -> bool) -> 'a t -> 'a t
- (** Filter out elements that do not satisfy the predicate. *)
-
- val take_while : ('a -> bool) -> 'a t -> 'a t
- (** Take elements while they satisfy the predicate *)
-
- val drop_while : ('a -> bool) -> 'a t -> 'a t
- (** Drop elements while they satisfy the predicate *)
-
- val filter_map : ('a -> 'b option) -> 'a t -> 'b t
- (** Maps some elements to 'b, drop the other ones *)
-
- val zip_index : 'a t -> (int * 'a) t
- (** Zip elements with their index in the enum *)
-
- val unzip : ('a * 'b) t -> 'a t * 'b t
- (** Unzip into two sequences, splitting each pair *)
-
- val partition : ('a -> bool) -> 'a t -> 'a t * 'a t
- (** [partition p l] returns the elements that satisfy [p],
- and the elements that do not satisfy [p] *)
-
- val for_all : ('a -> bool) -> 'a t -> bool
- (** Is the predicate true for all elements? *)
-
- val exists : ('a -> bool) -> 'a t -> bool
- (** Is the predicate true for at least one element? *)
-
- val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
- (** Minimum element, according to the given comparison function.
- @raise Invalid_argument if the generator is empty *)
-
- val max : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
- (** Maximum element, see {!min}
- @raise Invalid_argument if the generator is empty *)
-
- val eq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool
- (** Equality of generators. *)
-
- val lexico : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int
- (** Lexicographic comparison of generators. If a generator is a prefix
- of the other one, it is considered smaller. *)
-
- val compare : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int
- (** Synonym for {! lexico} *)
-
- val find : ('a -> bool) -> 'a t -> 'a option
- (** [find p e] returns the first element of [e] to satisfy [p],
- or None. *)
-
- val sum : int t -> int
- (** Sum of all elements *)
-
- (** {2 Multiple iterators} *)
-
- val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
- (** Map on the two sequences. Stops once one of them is exhausted.*)
-
- val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit
- (** Iterate on the two sequences. Stops once one of them is exhausted.*)
-
- val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
- (** Fold the common prefix of the two iterators *)
-
- val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
- (** Succeeds if all pairs of elements satisfy the predicate.
- Ignores elements of an iterator if the other runs dry. *)
-
- val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
- (** Succeeds if some pair of elements satisfy the predicate.
- Ignores elements of an iterator if the other runs dry. *)
-
- val zip_with : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
- (** Combine common part of the enums (stops when one is exhausted) *)
-
- val zip : 'a t -> 'b t -> ('a * 'b) t
- (** Zip together the common part of the enums *)
-
- (** {2 Complex combinators} *)
-
- val merge : 'a gen t -> 'a t
- (** Pick elements fairly in each sub-generator. The merge of enums
- [e1, e2, ... ] picks elements in [e1], [e2],
- in [e3], [e1], [e2] .... Once a generator is empty, it is skipped;
- when they are all empty, and none remains in the input,
- their merge is also empty.
- For instance, [merge [1;3;5] [2;4;6]] will be, in disorder, [1;2;3;4;5;6]. *)
-
- val intersection : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> 'a t
- (** Intersection of two sorted sequences. Only elements that occur in both
- inputs appear in the output *)
-
- val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> 'a t
- (** Merge two sorted sequences into a sorted sequence *)
-
- val sorted_merge_n : ?cmp:('a -> 'a -> int) -> 'a t list -> 'a t
- (** Sorted merge of multiple sorted sequences *)
-
- val tee : ?n:int -> 'a t -> 'a gen list
- (** Duplicate the enum into [n] generators (default 2). The generators
- share the same underlying instance of the enum, so the optimal case is
- when they are consumed evenly *)
-
- val round_robin : ?n:int -> 'a t -> 'a gen list
- (** Split the enum into [n] generators in a fair way. Elements with
- [index = k mod n] with go to the k-th enum. [n] default value
- is 2. *)
-
- val interleave : 'a t -> 'a t -> 'a t
- (** [interleave a b] yields an element of [a], then an element of [b],
- and so on. When a generator is exhausted, this behaves like the
- other generator. *)
-
- val intersperse : 'a -> 'a t -> 'a t
- (** Put the separator element between all elements of the given enum *)
-
- val product : 'a t -> 'b t -> ('a * 'b) t
- (** Cartesian product, in no predictable order. Works even if some of the
- arguments are infinite. *)
-
- val group : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
- (** Group equal consecutive elements together. *)
-
- val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
- (** Remove consecutive duplicate elements. Basically this is
- like [fun e -> map List.hd (group e)]. *)
-
- val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
- (** Sort according to the given comparison function. The enum must be finite. *)
-
- val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
- (** Sort and remove duplicates. The enum must be finite. *)
-
- val chunks : int -> 'a t -> 'a array t
- (** [chunks n e] returns a generator of arrays of length [n], composed
- of successive elements of [e]. The last array may be smaller
- than [n] *)
-
- val permutations : 'a t -> 'a list t
- (** Permutations of the enum.
- @since 0.2.2 *)
-
- val combinations : int -> 'a t -> 'a list t
- (** Combinations of given length. The ordering of the elements within
- each combination is unspecified.
- Example (ignoring ordering):
- [combinations 2 (1--3) |> to_list = [[1;2]; [1;3]; [2;3]]]
- @since 0.2.2 *)
-
- val power_set : 'a t -> 'a list t
- (** All subsets of the enum (in no particular order). The ordering of
- the elements within each subset is unspecified.
- @since 0.2.2 *)
-
- (** {2 Basic conversion functions} *)
-
- val of_list : 'a list -> 'a t
- (** Enumerate elements of the list *)
-
- val to_list : 'a t -> 'a list
- (** non tail-call trasnformation to list, in the same order *)
-
- val to_rev_list : 'a t -> 'a list
- (** Tail call conversion to list, in reverse order (more efficient) *)
-
- val to_array : 'a t -> 'a array
- (** Convert the enum to an array (not very efficient) *)
-
- val of_array : ?start:int -> ?len:int -> 'a array -> 'a t
- (** Iterate on (a slice of) the given array *)
-
- val rand_int : int -> int t
- (** Random ints in the given range. *)
-
- val int_range : int -> int -> int t
- (** [int_range a b] enumerates integers between [a] and [b], included. [a]
- is assumed to be smaller than [b]. *)
-
- module Infix : sig
- val (--) : int -> int -> int t
- (** Synonym for {! int_range} *)
-
- val (>>=) : 'a t -> ('a -> 'b gen) -> 'b t
- (** Monadic bind operator *)
- end
-
- val (--) : int -> int -> int t
- (** Synonym for {! int_range} *)
-
- val (>>=) : 'a t -> ('a -> 'b gen) -> 'b t
- (** Monadic bind operator *)
-
- val pp : ?start:string -> ?stop:string -> ?sep:string -> ?horizontal:bool ->
- (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit
- (** Pretty print the content of the generator on a formatter. *)
-end
-
diff --git a/gen/myocamlbuild.ml b/gen/myocamlbuild.ml
deleted file mode 100644
index 57fcede3..00000000
--- a/gen/myocamlbuild.ml
+++ /dev/null
@@ -1,623 +0,0 @@
-(* OASIS_START *)
-(* DO NOT EDIT (digest: 8b03085ed54d5ff9a8cbd756150607bd) *)
-module OASISGettext = struct
-(* # 22 "src/oasis/OASISGettext.ml" *)
-
-
- let ns_ str =
- str
-
-
- let s_ str =
- str
-
-
- let f_ (str: ('a, 'b, 'c, 'd) format4) =
- str
-
-
- let fn_ fmt1 fmt2 n =
- if n = 1 then
- fmt1^^""
- else
- fmt2^^""
-
-
- let init =
- []
-
-
-end
-
-module OASISExpr = struct
-(* # 22 "src/oasis/OASISExpr.ml" *)
-
-
-
-
-
- open OASISGettext
-
-
- type test = string
-
-
- type flag = string
-
-
- type t =
- | EBool of bool
- | ENot of t
- | EAnd of t * t
- | EOr of t * t
- | EFlag of flag
- | ETest of test * string
-
-
-
- type 'a choices = (t * 'a) list
-
-
- let eval var_get t =
- let rec eval' =
- function
- | EBool b ->
- b
-
- | ENot e ->
- not (eval' e)
-
- | EAnd (e1, e2) ->
- (eval' e1) && (eval' e2)
-
- | EOr (e1, e2) ->
- (eval' e1) || (eval' e2)
-
- | EFlag nm ->
- let v =
- var_get nm
- in
- assert(v = "true" || v = "false");
- (v = "true")
-
- | ETest (nm, vl) ->
- let v =
- var_get nm
- in
- (v = vl)
- in
- eval' t
-
-
- let choose ?printer ?name var_get lst =
- let rec choose_aux =
- function
- | (cond, vl) :: tl ->
- if eval var_get cond then
- vl
- else
- choose_aux tl
- | [] ->
- let str_lst =
- if lst = [] then
- s_ ""
- else
- String.concat
- (s_ ", ")
- (List.map
- (fun (cond, vl) ->
- match printer with
- | Some p -> p vl
- | None -> s_ "")
- lst)
- in
- match name with
- | Some nm ->
- failwith
- (Printf.sprintf
- (f_ "No result for the choice list '%s': %s")
- nm str_lst)
- | None ->
- failwith
- (Printf.sprintf
- (f_ "No result for a choice list: %s")
- str_lst)
- in
- choose_aux (List.rev lst)
-
-
-end
-
-
-# 132 "myocamlbuild.ml"
-module BaseEnvLight = struct
-(* # 22 "src/base/BaseEnvLight.ml" *)
-
-
- module MapString = Map.Make(String)
-
-
- type t = string MapString.t
-
-
- let default_filename =
- Filename.concat
- (Sys.getcwd ())
- "setup.data"
-
-
- let load ?(allow_empty=false) ?(filename=default_filename) () =
- if Sys.file_exists filename then
- begin
- let chn =
- open_in_bin filename
- in
- let st =
- Stream.of_channel chn
- in
- let line =
- ref 1
- in
- let st_line =
- Stream.from
- (fun _ ->
- try
- match Stream.next st with
- | '\n' -> incr line; Some '\n'
- | c -> Some c
- with Stream.Failure -> None)
- in
- let lexer =
- Genlex.make_lexer ["="] st_line
- in
- let rec read_file mp =
- match Stream.npeek 3 lexer with
- | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
- Stream.junk lexer;
- Stream.junk lexer;
- Stream.junk lexer;
- read_file (MapString.add nm value mp)
- | [] ->
- mp
- | _ ->
- failwith
- (Printf.sprintf
- "Malformed data file '%s' line %d"
- filename !line)
- in
- let mp =
- read_file MapString.empty
- in
- close_in chn;
- mp
- end
- else if allow_empty then
- begin
- MapString.empty
- end
- else
- begin
- failwith
- (Printf.sprintf
- "Unable to load environment, the file '%s' doesn't exist."
- filename)
- end
-
-
- let rec var_expand str env =
- let buff =
- Buffer.create ((String.length str) * 2)
- in
- Buffer.add_substitute
- buff
- (fun var ->
- try
- var_expand (MapString.find var env) env
- with Not_found ->
- failwith
- (Printf.sprintf
- "No variable %s defined when trying to expand %S."
- var
- str))
- str;
- Buffer.contents buff
-
-
- let var_get name env =
- var_expand (MapString.find name env) env
-
-
- let var_choose lst env =
- OASISExpr.choose
- (fun nm -> var_get nm env)
- lst
-end
-
-
-# 237 "myocamlbuild.ml"
-module MyOCamlbuildFindlib = struct
-(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
-
-
- (** OCamlbuild extension, copied from
- * http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
- * by N. Pouillard and others
- *
- * Updated on 2009/02/28
- *
- * Modified by Sylvain Le Gall
- *)
- open Ocamlbuild_plugin
-
- type conf =
- { no_automatic_syntax: bool;
- }
-
- (* these functions are not really officially exported *)
- let run_and_read =
- Ocamlbuild_pack.My_unix.run_and_read
-
-
- let blank_sep_strings =
- Ocamlbuild_pack.Lexers.blank_sep_strings
-
-
- let exec_from_conf exec =
- let exec =
- let env_filename = Pathname.basename BaseEnvLight.default_filename in
- let env = BaseEnvLight.load ~filename:env_filename ~allow_empty:true () in
- try
- BaseEnvLight.var_get exec env
- with Not_found ->
- Printf.eprintf "W: Cannot get variable %s\n" exec;
- exec
- in
- let fix_win32 str =
- if Sys.os_type = "Win32" then begin
- let buff = Buffer.create (String.length str) in
- (* Adapt for windowsi, ocamlbuild + win32 has a hard time to handle '\\'.
- *)
- String.iter
- (fun c -> Buffer.add_char buff (if c = '\\' then '/' else c))
- str;
- Buffer.contents buff
- end else begin
- str
- end
- in
- fix_win32 exec
-
- let split s ch =
- let buf = Buffer.create 13 in
- let x = ref [] in
- let flush () =
- x := (Buffer.contents buf) :: !x;
- Buffer.clear buf
- in
- String.iter
- (fun c ->
- if c = ch then
- flush ()
- else
- Buffer.add_char buf c)
- s;
- flush ();
- List.rev !x
-
-
- let split_nl s = split s '\n'
-
-
- let before_space s =
- try
- String.before s (String.index s ' ')
- with Not_found -> s
-
- (* ocamlfind command *)
- let ocamlfind x = S[Sh (exec_from_conf "ocamlfind"); x]
-
- (* This lists all supported packages. *)
- let find_packages () =
- List.map before_space (split_nl & run_and_read (exec_from_conf "ocamlfind" ^ " list"))
-
-
- (* Mock to list available syntaxes. *)
- let find_syntaxes () = ["camlp4o"; "camlp4r"]
-
-
- let well_known_syntax = [
- "camlp4.quotations.o";
- "camlp4.quotations.r";
- "camlp4.exceptiontracer";
- "camlp4.extend";
- "camlp4.foldgenerator";
- "camlp4.listcomprehension";
- "camlp4.locationstripper";
- "camlp4.macro";
- "camlp4.mapgenerator";
- "camlp4.metagenerator";
- "camlp4.profiler";
- "camlp4.tracer"
- ]
-
-
- let dispatch conf =
- function
- | After_options ->
- (* By using Before_options one let command line options have an higher
- * priority on the contrary using After_options will guarantee to have
- * the higher priority override default commands by ocamlfind ones *)
- Options.ocamlc := ocamlfind & A"ocamlc";
- Options.ocamlopt := ocamlfind & A"ocamlopt";
- Options.ocamldep := ocamlfind & A"ocamldep";
- Options.ocamldoc := ocamlfind & A"ocamldoc";
- Options.ocamlmktop := ocamlfind & A"ocamlmktop";
- Options.ocamlmklib := ocamlfind & A"ocamlmklib"
-
- | After_rules ->
-
- (* When one link an OCaml library/binary/package, one should use
- * -linkpkg *)
- flag ["ocaml"; "link"; "program"] & A"-linkpkg";
-
- if not (conf.no_automatic_syntax) then begin
- (* For each ocamlfind package one inject the -package option when
- * compiling, computing dependencies, generating documentation and
- * linking. *)
- List.iter
- begin fun pkg ->
- let base_args = [A"-package"; A pkg] in
- (* TODO: consider how to really choose camlp4o or camlp4r. *)
- let syn_args = [A"-syntax"; A "camlp4o"] in
- let (args, pargs) =
- (* Heuristic to identify syntax extensions: whether they end in
- ".syntax"; some might not.
- *)
- if Filename.check_suffix pkg "syntax" ||
- List.mem pkg well_known_syntax then
- (syn_args @ base_args, syn_args)
- else
- (base_args, [])
- in
- flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
- flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
- flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
- flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
- flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
-
- (* TODO: Check if this is allowed for OCaml < 3.12.1 *)
- flag ["ocaml"; "compile"; "package("^pkg^")"] & S pargs;
- flag ["ocaml"; "ocamldep"; "package("^pkg^")"] & S pargs;
- flag ["ocaml"; "doc"; "package("^pkg^")"] & S pargs;
- flag ["ocaml"; "infer_interface"; "package("^pkg^")"] & S pargs;
- end
- (find_packages ());
- end;
-
- (* Like -package but for extensions syntax. Morover -syntax is useless
- * when linking. *)
- List.iter begin fun syntax ->
- flag ["ocaml"; "compile"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
- flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
- flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
- flag ["ocaml"; "infer_interface"; "syntax_"^syntax] &
- S[A"-syntax"; A syntax];
- end (find_syntaxes ());
-
- (* The default "thread" tag is not compatible with ocamlfind.
- * Indeed, the default rules add the "threads.cma" or "threads.cmxa"
- * options when using this tag. When using the "-linkpkg" option with
- * ocamlfind, this module will then be added twice on the command line.
- *
- * To solve this, one approach is to add the "-thread" option when using
- * the "threads" package using the previous plugin.
- *)
- flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
- flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
- flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
- flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
- flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
- flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
- flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
- flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
-
- | _ ->
- ()
-end
-
-module MyOCamlbuildBase = struct
-(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
-
-
- (** Base functions for writing myocamlbuild.ml
- @author Sylvain Le Gall
- *)
-
-
-
-
-
- open Ocamlbuild_plugin
- module OC = Ocamlbuild_pack.Ocaml_compiler
-
-
- type dir = string
- type file = string
- type name = string
- type tag = string
-
-
-(* # 62 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
-
-
- type t =
- {
- lib_ocaml: (name * dir list * string list) list;
- lib_c: (name * dir * file list) list;
- flags: (tag list * (spec OASISExpr.choices)) list;
- (* Replace the 'dir: include' from _tags by a precise interdepends in
- * directory.
- *)
- includes: (dir * dir list) list;
- }
-
-
- let env_filename =
- Pathname.basename
- BaseEnvLight.default_filename
-
-
- let dispatch_combine lst =
- fun e ->
- List.iter
- (fun dispatch -> dispatch e)
- lst
-
-
- let tag_libstubs nm =
- "use_lib"^nm^"_stubs"
-
-
- let nm_libstubs nm =
- nm^"_stubs"
-
-
- let dispatch t e =
- let env =
- BaseEnvLight.load
- ~filename:env_filename
- ~allow_empty:true
- ()
- in
- match e with
- | Before_options ->
- let no_trailing_dot s =
- if String.length s >= 1 && s.[0] = '.' then
- String.sub s 1 ((String.length s) - 1)
- else
- s
- in
- List.iter
- (fun (opt, var) ->
- try
- opt := no_trailing_dot (BaseEnvLight.var_get var env)
- with Not_found ->
- Printf.eprintf "W: Cannot get variable %s\n" var)
- [
- Options.ext_obj, "ext_obj";
- Options.ext_lib, "ext_lib";
- Options.ext_dll, "ext_dll";
- ]
-
- | After_rules ->
- (* Declare OCaml libraries *)
- List.iter
- (function
- | nm, [], intf_modules ->
- ocaml_lib nm;
- let cmis =
- List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
- intf_modules in
- dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
- | nm, dir :: tl, intf_modules ->
- ocaml_lib ~dir:dir (dir^"/"^nm);
- List.iter
- (fun dir ->
- List.iter
- (fun str ->
- flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir]))
- ["compile"; "infer_interface"; "doc"])
- tl;
- let cmis =
- List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
- intf_modules in
- dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
- cmis)
- t.lib_ocaml;
-
- (* Declare directories dependencies, replace "include" in _tags. *)
- List.iter
- (fun (dir, include_dirs) ->
- Pathname.define_context dir include_dirs)
- t.includes;
-
- (* Declare C libraries *)
- List.iter
- (fun (lib, dir, headers) ->
- (* Handle C part of library *)
- flag ["link"; "library"; "ocaml"; "byte"; tag_libstubs lib]
- (S[A"-dllib"; A("-l"^(nm_libstubs lib)); A"-cclib";
- A("-l"^(nm_libstubs lib))]);
-
- flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
- (S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
-
- flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
- (S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
-
- (* When ocaml link something that use the C library, then one
- need that file to be up to date.
- This holds both for programs and for libraries.
- *)
- dep ["link"; "ocaml"; tag_libstubs lib]
- [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
-
- dep ["compile"; "ocaml"; tag_libstubs lib]
- [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
-
- (* TODO: be more specific about what depends on headers *)
- (* Depends on .h files *)
- dep ["compile"; "c"]
- headers;
-
- (* Setup search path for lib *)
- flag ["link"; "ocaml"; "use_"^lib]
- (S[A"-I"; P(dir)]);
- )
- t.lib_c;
-
- (* Add flags *)
- List.iter
- (fun (tags, cond_specs) ->
- let spec = BaseEnvLight.var_choose cond_specs env in
- let rec eval_specs =
- function
- | S lst -> S (List.map eval_specs lst)
- | A str -> A (BaseEnvLight.var_expand str env)
- | spec -> spec
- in
- flag tags & (eval_specs spec))
- t.flags
- | _ ->
- ()
-
-
- let dispatch_default conf t =
- dispatch_combine
- [
- dispatch t;
- MyOCamlbuildFindlib.dispatch conf;
- ]
-
-
-end
-
-
-# 606 "myocamlbuild.ml"
-open Ocamlbuild_plugin;;
-let package_default =
- {
- MyOCamlbuildBase.lib_ocaml = [("gen", [], [])];
- lib_c = [];
- flags = [];
- includes = []
- }
- ;;
-
-let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
-
-let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
-
-# 622 "myocamlbuild.ml"
-(* OASIS_STOP *)
-Ocamlbuild_plugin.dispatch dispatch_default;;
diff --git a/gen/setup.ml b/gen/setup.ml
deleted file mode 100644
index fe876747..00000000
--- a/gen/setup.ml
+++ /dev/null
@@ -1,7150 +0,0 @@
-(* setup.ml generated for the first time by OASIS v0.4.0 *)
-
-(* OASIS_START *)
-(* DO NOT EDIT (digest: 751af72d4e295f56a78e6ed6d61afa74) *)
-(*
- Regenerated by OASIS v0.4.5
- Visit http://oasis.forge.ocamlcore.org for more information and
- documentation about functions used in this file.
-*)
-module OASISGettext = struct
-(* # 22 "src/oasis/OASISGettext.ml" *)
-
-
- let ns_ str =
- str
-
-
- let s_ str =
- str
-
-
- let f_ (str: ('a, 'b, 'c, 'd) format4) =
- str
-
-
- let fn_ fmt1 fmt2 n =
- if n = 1 then
- fmt1^^""
- else
- fmt2^^""
-
-
- let init =
- []
-
-
-end
-
-module OASISContext = struct
-(* # 22 "src/oasis/OASISContext.ml" *)
-
-
- open OASISGettext
-
-
- type level =
- [ `Debug
- | `Info
- | `Warning
- | `Error]
-
-
- type t =
- {
- (* TODO: replace this by a proplist. *)
- quiet: bool;
- info: bool;
- debug: bool;
- ignore_plugins: bool;
- ignore_unknown_fields: bool;
- printf: level -> string -> unit;
- }
-
-
- let printf lvl str =
- let beg =
- match lvl with
- | `Error -> s_ "E: "
- | `Warning -> s_ "W: "
- | `Info -> s_ "I: "
- | `Debug -> s_ "D: "
- in
- prerr_endline (beg^str)
-
-
- let default =
- ref
- {
- quiet = false;
- info = false;
- debug = false;
- ignore_plugins = false;
- ignore_unknown_fields = false;
- printf = printf;
- }
-
-
- let quiet =
- {!default with quiet = true}
-
-
- let fspecs () =
- (* TODO: don't act on default. *)
- let ignore_plugins = ref false in
- ["-quiet",
- Arg.Unit (fun () -> default := {!default with quiet = true}),
- s_ " Run quietly";
-
- "-info",
- Arg.Unit (fun () -> default := {!default with info = true}),
- s_ " Display information message";
-
-
- "-debug",
- Arg.Unit (fun () -> default := {!default with debug = true}),
- s_ " Output debug message";
-
- "-ignore-plugins",
- Arg.Set ignore_plugins,
- s_ " Ignore plugin's field.";
-
- "-C",
- (* TODO: remove this chdir. *)
- Arg.String (fun str -> Sys.chdir str),
- s_ "dir Change directory before running."],
- fun () -> {!default with ignore_plugins = !ignore_plugins}
-end
-
-module OASISString = struct
-(* # 22 "src/oasis/OASISString.ml" *)
-
-
- (** Various string utilities.
-
- Mostly inspired by extlib and batteries ExtString and BatString libraries.
-
- @author Sylvain Le Gall
- *)
-
-
- let nsplitf str f =
- if str = "" then
- []
- else
- let buf = Buffer.create 13 in
- let lst = ref [] in
- let push () =
- lst := Buffer.contents buf :: !lst;
- Buffer.clear buf
- in
- let str_len = String.length str in
- for i = 0 to str_len - 1 do
- if f str.[i] then
- push ()
- else
- Buffer.add_char buf str.[i]
- done;
- push ();
- List.rev !lst
-
-
- (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
- separator.
- *)
- let nsplit str c =
- nsplitf str ((=) c)
-
-
- let find ~what ?(offset=0) str =
- let what_idx = ref 0 in
- let str_idx = ref offset in
- while !str_idx < String.length str &&
- !what_idx < String.length what do
- if str.[!str_idx] = what.[!what_idx] then
- incr what_idx
- else
- what_idx := 0;
- incr str_idx
- done;
- if !what_idx <> String.length what then
- raise Not_found
- else
- !str_idx - !what_idx
-
-
- let sub_start str len =
- let str_len = String.length str in
- if len >= str_len then
- ""
- else
- String.sub str len (str_len - len)
-
-
- let sub_end ?(offset=0) str len =
- let str_len = String.length str in
- if len >= str_len then
- ""
- else
- String.sub str 0 (str_len - len)
-
-
- let starts_with ~what ?(offset=0) str =
- let what_idx = ref 0 in
- let str_idx = ref offset in
- let ok = ref true in
- while !ok &&
- !str_idx < String.length str &&
- !what_idx < String.length what do
- if str.[!str_idx] = what.[!what_idx] then
- incr what_idx
- else
- ok := false;
- incr str_idx
- done;
- if !what_idx = String.length what then
- true
- else
- false
-
-
- let strip_starts_with ~what str =
- if starts_with ~what str then
- sub_start str (String.length what)
- else
- raise Not_found
-
-
- let ends_with ~what ?(offset=0) str =
- let what_idx = ref ((String.length what) - 1) in
- let str_idx = ref ((String.length str) - 1) in
- let ok = ref true in
- while !ok &&
- offset <= !str_idx &&
- 0 <= !what_idx do
- if str.[!str_idx] = what.[!what_idx] then
- decr what_idx
- else
- ok := false;
- decr str_idx
- done;
- if !what_idx = -1 then
- true
- else
- false
-
-
- let strip_ends_with ~what str =
- if ends_with ~what str then
- sub_end str (String.length what)
- else
- raise Not_found
-
-
- let replace_chars f s =
- let buf = Buffer.create (String.length s) in
- String.iter (fun c -> Buffer.add_char buf (f c)) s;
- Buffer.contents buf
-
-
-end
-
-module OASISUtils = struct
-(* # 22 "src/oasis/OASISUtils.ml" *)
-
-
- open OASISGettext
-
-
- module MapExt =
- struct
- module type S =
- sig
- include Map.S
- val add_list: 'a t -> (key * 'a) list -> 'a t
- val of_list: (key * 'a) list -> 'a t
- val to_list: 'a t -> (key * 'a) list
- end
-
- module Make (Ord: Map.OrderedType) =
- struct
- include Map.Make(Ord)
-
- let rec add_list t =
- function
- | (k, v) :: tl -> add_list (add k v t) tl
- | [] -> t
-
- let of_list lst = add_list empty lst
-
- let to_list t = fold (fun k v acc -> (k, v) :: acc) t []
- end
- end
-
-
- module MapString = MapExt.Make(String)
-
-
- module SetExt =
- struct
- module type S =
- sig
- include Set.S
- val add_list: t -> elt list -> t
- val of_list: elt list -> t
- val to_list: t -> elt list
- end
-
- module Make (Ord: Set.OrderedType) =
- struct
- include Set.Make(Ord)
-
- let rec add_list t =
- function
- | e :: tl -> add_list (add e t) tl
- | [] -> t
-
- let of_list lst = add_list empty lst
-
- let to_list = elements
- end
- end
-
-
- module SetString = SetExt.Make(String)
-
-
- let compare_csl s1 s2 =
- String.compare (String.lowercase s1) (String.lowercase s2)
-
-
- module HashStringCsl =
- Hashtbl.Make
- (struct
- type t = string
-
- let equal s1 s2 =
- (String.lowercase s1) = (String.lowercase s2)
-
- let hash s =
- Hashtbl.hash (String.lowercase s)
- end)
-
- module SetStringCsl =
- SetExt.Make
- (struct
- type t = string
- let compare = compare_csl
- end)
-
-
- let varname_of_string ?(hyphen='_') s =
- if String.length s = 0 then
- begin
- invalid_arg "varname_of_string"
- end
- else
- begin
- let buf =
- OASISString.replace_chars
- (fun c ->
- if ('a' <= c && c <= 'z')
- ||
- ('A' <= c && c <= 'Z')
- ||
- ('0' <= c && c <= '9') then
- c
- else
- hyphen)
- s;
- in
- let buf =
- (* Start with a _ if digit *)
- if '0' <= s.[0] && s.[0] <= '9' then
- "_"^buf
- else
- buf
- in
- String.lowercase buf
- end
-
-
- let varname_concat ?(hyphen='_') p s =
- let what = String.make 1 hyphen in
- let p =
- try
- OASISString.strip_ends_with ~what p
- with Not_found ->
- p
- in
- let s =
- try
- OASISString.strip_starts_with ~what s
- with Not_found ->
- s
- in
- p^what^s
-
-
- let is_varname str =
- str = varname_of_string str
-
-
- let failwithf fmt = Printf.ksprintf failwith fmt
-
-
-end
-
-module PropList = struct
-(* # 22 "src/oasis/PropList.ml" *)
-
-
- open OASISGettext
-
-
- type name = string
-
-
- exception Not_set of name * string option
- exception No_printer of name
- exception Unknown_field of name * name
-
-
- let () =
- Printexc.register_printer
- (function
- | Not_set (nm, Some rsn) ->
- Some
- (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn)
- | Not_set (nm, None) ->
- Some
- (Printf.sprintf (f_ "Field '%s' is not set") nm)
- | No_printer nm ->
- Some
- (Printf.sprintf (f_ "No default printer for value %s") nm)
- | Unknown_field (nm, schm) ->
- Some
- (Printf.sprintf
- (f_ "Field %s is not defined in schema %s") nm schm)
- | _ ->
- None)
-
-
- module Data =
- struct
- type t =
- (name, unit -> unit) Hashtbl.t
-
- let create () =
- Hashtbl.create 13
-
- let clear t =
- Hashtbl.clear t
-
-
-(* # 78 "src/oasis/PropList.ml" *)
- end
-
-
- module Schema =
- struct
- type ('ctxt, 'extra) value =
- {
- get: Data.t -> string;
- set: Data.t -> ?context:'ctxt -> string -> unit;
- help: (unit -> string) option;
- extra: 'extra;
- }
-
- type ('ctxt, 'extra) t =
- {
- name: name;
- fields: (name, ('ctxt, 'extra) value) Hashtbl.t;
- order: name Queue.t;
- name_norm: string -> string;
- }
-
- let create ?(case_insensitive=false) nm =
- {
- name = nm;
- fields = Hashtbl.create 13;
- order = Queue.create ();
- name_norm =
- (if case_insensitive then
- String.lowercase
- else
- fun s -> s);
- }
-
- let add t nm set get extra help =
- let key =
- t.name_norm nm
- in
-
- if Hashtbl.mem t.fields key then
- failwith
- (Printf.sprintf
- (f_ "Field '%s' is already defined in schema '%s'")
- nm t.name);
- Hashtbl.add
- t.fields
- key
- {
- set = set;
- get = get;
- help = help;
- extra = extra;
- };
- Queue.add nm t.order
-
- let mem t nm =
- Hashtbl.mem t.fields nm
-
- let find t nm =
- try
- Hashtbl.find t.fields (t.name_norm nm)
- with Not_found ->
- raise (Unknown_field (nm, t.name))
-
- let get t data nm =
- (find t nm).get data
-
- let set t data nm ?context x =
- (find t nm).set
- data
- ?context
- x
-
- let fold f acc t =
- Queue.fold
- (fun acc k ->
- let v =
- find t k
- in
- f acc k v.extra v.help)
- acc
- t.order
-
- let iter f t =
- fold
- (fun () -> f)
- ()
- t
-
- let name t =
- t.name
- end
-
-
- module Field =
- struct
- type ('ctxt, 'value, 'extra) t =
- {
- set: Data.t -> ?context:'ctxt -> 'value -> unit;
- get: Data.t -> 'value;
- sets: Data.t -> ?context:'ctxt -> string -> unit;
- gets: Data.t -> string;
- help: (unit -> string) option;
- extra: 'extra;
- }
-
- let new_id =
- let last_id =
- ref 0
- in
- fun () -> incr last_id; !last_id
-
- let create ?schema ?name ?parse ?print ?default ?update ?help extra =
- (* Default value container *)
- let v =
- ref None
- in
-
- (* If name is not given, create unique one *)
- let nm =
- match name with
- | Some s -> s
- | None -> Printf.sprintf "_anon_%d" (new_id ())
- in
-
- (* Last chance to get a value: the default *)
- let default () =
- match default with
- | Some d -> d
- | None -> raise (Not_set (nm, Some (s_ "no default value")))
- in
-
- (* Get data *)
- let get data =
- (* Get value *)
- try
- (Hashtbl.find data nm) ();
- match !v with
- | Some x -> x
- | None -> default ()
- with Not_found ->
- default ()
- in
-
- (* Set data *)
- let set data ?context x =
- let x =
- match update with
- | Some f ->
- begin
- try
- f ?context (get data) x
- with Not_set _ ->
- x
- end
- | None ->
- x
- in
- Hashtbl.replace
- data
- nm
- (fun () -> v := Some x)
- in
-
- (* Parse string value, if possible *)
- let parse =
- match parse with
- | Some f ->
- f
- | None ->
- fun ?context s ->
- failwith
- (Printf.sprintf
- (f_ "Cannot parse field '%s' when setting value %S")
- nm
- s)
- in
-
- (* Set data, from string *)
- let sets data ?context s =
- set ?context data (parse ?context s)
- in
-
- (* Output value as string, if possible *)
- let print =
- match print with
- | Some f ->
- f
- | None ->
- fun _ -> raise (No_printer nm)
- in
-
- (* Get data, as a string *)
- let gets data =
- print (get data)
- in
-
- begin
- match schema with
- | Some t ->
- Schema.add t nm sets gets extra help
- | None ->
- ()
- end;
-
- {
- set = set;
- get = get;
- sets = sets;
- gets = gets;
- help = help;
- extra = extra;
- }
-
- let fset data t ?context x =
- t.set data ?context x
-
- let fget data t =
- t.get data
-
- let fsets data t ?context s =
- t.sets data ?context s
-
- let fgets data t =
- t.gets data
- end
-
-
- module FieldRO =
- struct
- let create ?schema ?name ?parse ?print ?default ?update ?help extra =
- let fld =
- Field.create ?schema ?name ?parse ?print ?default ?update ?help extra
- in
- fun data -> Field.fget data fld
- end
-end
-
-module OASISMessage = struct
-(* # 22 "src/oasis/OASISMessage.ml" *)
-
-
- open OASISGettext
- open OASISContext
-
-
- let generic_message ~ctxt lvl fmt =
- let cond =
- if ctxt.quiet then
- false
- else
- match lvl with
- | `Debug -> ctxt.debug
- | `Info -> ctxt.info
- | _ -> true
- in
- Printf.ksprintf
- (fun str ->
- if cond then
- begin
- ctxt.printf lvl str
- end)
- fmt
-
-
- let debug ~ctxt fmt =
- generic_message ~ctxt `Debug fmt
-
-
- let info ~ctxt fmt =
- generic_message ~ctxt `Info fmt
-
-
- let warning ~ctxt fmt =
- generic_message ~ctxt `Warning fmt
-
-
- let error ~ctxt fmt =
- generic_message ~ctxt `Error fmt
-
-end
-
-module OASISVersion = struct
-(* # 22 "src/oasis/OASISVersion.ml" *)
-
-
- open OASISGettext
-
-
-
-
-
- type s = string
-
-
- type t = string
-
-
- type comparator =
- | VGreater of t
- | VGreaterEqual of t
- | VEqual of t
- | VLesser of t
- | VLesserEqual of t
- | VOr of comparator * comparator
- | VAnd of comparator * comparator
-
-
-
- (* Range of allowed characters *)
- let is_digit c =
- '0' <= c && c <= '9'
-
-
- let is_alpha c =
- ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
-
-
- let is_special =
- function
- | '.' | '+' | '-' | '~' -> true
- | _ -> false
-
-
- let rec version_compare v1 v2 =
- if v1 <> "" || v2 <> "" then
- begin
- (* Compare ascii string, using special meaning for version
- * related char
- *)
- let val_ascii c =
- if c = '~' then -1
- else if is_digit c then 0
- else if c = '\000' then 0
- else if is_alpha c then Char.code c
- else (Char.code c) + 256
- in
-
- let len1 = String.length v1 in
- let len2 = String.length v2 in
-
- let p = ref 0 in
-
- (** Compare ascii part *)
- let compare_vascii () =
- let cmp = ref 0 in
- while !cmp = 0 &&
- !p < len1 && !p < len2 &&
- not (is_digit v1.[!p] && is_digit v2.[!p]) do
- cmp := (val_ascii v1.[!p]) - (val_ascii v2.[!p]);
- incr p
- done;
- if !cmp = 0 && !p < len1 && !p = len2 then
- val_ascii v1.[!p]
- else if !cmp = 0 && !p = len1 && !p < len2 then
- - (val_ascii v2.[!p])
- else
- !cmp
- in
-
- (** Compare digit part *)
- let compare_digit () =
- let extract_int v p =
- let start_p = !p in
- while !p < String.length v && is_digit v.[!p] do
- incr p
- done;
- let substr =
- String.sub v !p ((String.length v) - !p)
- in
- let res =
- match String.sub v start_p (!p - start_p) with
- | "" -> 0
- | s -> int_of_string s
- in
- res, substr
- in
- let i1, tl1 = extract_int v1 (ref !p) in
- let i2, tl2 = extract_int v2 (ref !p) in
- i1 - i2, tl1, tl2
- in
-
- match compare_vascii () with
- | 0 ->
- begin
- match compare_digit () with
- | 0, tl1, tl2 ->
- if tl1 <> "" && is_digit tl1.[0] then
- 1
- else if tl2 <> "" && is_digit tl2.[0] then
- -1
- else
- version_compare tl1 tl2
- | n, _, _ ->
- n
- end
- | n ->
- n
- end
- else
- begin
- 0
- end
-
-
- let version_of_string str = str
-
-
- let string_of_version t = t
-
-
- let version_compare_string s1 s2 =
- version_compare (version_of_string s1) (version_of_string s2)
-
-
- let chop t =
- try
- let pos =
- String.rindex t '.'
- in
- String.sub t 0 pos
- with Not_found ->
- t
-
-
- let rec comparator_apply v op =
- match op with
- | VGreater cv ->
- (version_compare v cv) > 0
- | VGreaterEqual cv ->
- (version_compare v cv) >= 0
- | VLesser cv ->
- (version_compare v cv) < 0
- | VLesserEqual cv ->
- (version_compare v cv) <= 0
- | VEqual cv ->
- (version_compare v cv) = 0
- | VOr (op1, op2) ->
- (comparator_apply v op1) || (comparator_apply v op2)
- | VAnd (op1, op2) ->
- (comparator_apply v op1) && (comparator_apply v op2)
-
-
- let rec string_of_comparator =
- function
- | VGreater v -> "> "^(string_of_version v)
- | VEqual v -> "= "^(string_of_version v)
- | VLesser v -> "< "^(string_of_version v)
- | VGreaterEqual v -> ">= "^(string_of_version v)
- | VLesserEqual v -> "<= "^(string_of_version v)
- | VOr (c1, c2) ->
- (string_of_comparator c1)^" || "^(string_of_comparator c2)
- | VAnd (c1, c2) ->
- (string_of_comparator c1)^" && "^(string_of_comparator c2)
-
-
- let rec varname_of_comparator =
- let concat p v =
- OASISUtils.varname_concat
- p
- (OASISUtils.varname_of_string
- (string_of_version v))
- in
- function
- | VGreater v -> concat "gt" v
- | VLesser v -> concat "lt" v
- | VEqual v -> concat "eq" v
- | VGreaterEqual v -> concat "ge" v
- | VLesserEqual v -> concat "le" v
- | VOr (c1, c2) ->
- (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2)
- | VAnd (c1, c2) ->
- (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2)
-
-
- let rec comparator_ge v' =
- let cmp v = version_compare v v' >= 0 in
- function
- | VEqual v
- | VGreaterEqual v
- | VGreater v -> cmp v
- | VLesserEqual _
- | VLesser _ -> false
- | VOr (c1, c2) -> comparator_ge v' c1 || comparator_ge v' c2
- | VAnd (c1, c2) -> comparator_ge v' c1 && comparator_ge v' c2
-
-
-end
-
-module OASISLicense = struct
-(* # 22 "src/oasis/OASISLicense.ml" *)
-
-
- (** License for _oasis fields
- @author Sylvain Le Gall
- *)
-
-
-
-
-
- type license = string
-
-
- type license_exception = string
-
-
- type license_version =
- | Version of OASISVersion.t
- | VersionOrLater of OASISVersion.t
- | NoVersion
-
-
-
- type license_dep_5_unit =
- {
- license: license;
- excption: license_exception option;
- version: license_version;
- }
-
-
-
- type license_dep_5 =
- | DEP5Unit of license_dep_5_unit
- | DEP5Or of license_dep_5 list
- | DEP5And of license_dep_5 list
-
-
- type t =
- | DEP5License of license_dep_5
- | OtherLicense of string (* URL *)
-
-
-
-end
-
-module OASISExpr = struct
-(* # 22 "src/oasis/OASISExpr.ml" *)
-
-
-
-
-
- open OASISGettext
-
-
- type test = string
-
-
- type flag = string
-
-
- type t =
- | EBool of bool
- | ENot of t
- | EAnd of t * t
- | EOr of t * t
- | EFlag of flag
- | ETest of test * string
-
-
-
- type 'a choices = (t * 'a) list
-
-
- let eval var_get t =
- let rec eval' =
- function
- | EBool b ->
- b
-
- | ENot e ->
- not (eval' e)
-
- | EAnd (e1, e2) ->
- (eval' e1) && (eval' e2)
-
- | EOr (e1, e2) ->
- (eval' e1) || (eval' e2)
-
- | EFlag nm ->
- let v =
- var_get nm
- in
- assert(v = "true" || v = "false");
- (v = "true")
-
- | ETest (nm, vl) ->
- let v =
- var_get nm
- in
- (v = vl)
- in
- eval' t
-
-
- let choose ?printer ?name var_get lst =
- let rec choose_aux =
- function
- | (cond, vl) :: tl ->
- if eval var_get cond then
- vl
- else
- choose_aux tl
- | [] ->
- let str_lst =
- if lst = [] then
- s_ ""
- else
- String.concat
- (s_ ", ")
- (List.map
- (fun (cond, vl) ->
- match printer with
- | Some p -> p vl
- | None -> s_ "")
- lst)
- in
- match name with
- | Some nm ->
- failwith
- (Printf.sprintf
- (f_ "No result for the choice list '%s': %s")
- nm str_lst)
- | None ->
- failwith
- (Printf.sprintf
- (f_ "No result for a choice list: %s")
- str_lst)
- in
- choose_aux (List.rev lst)
-
-
-end
-
-module OASISText = struct
-(* # 22 "src/oasis/OASISText.ml" *)
-
-
-
- type elt =
- | Para of string
- | Verbatim of string
- | BlankLine
-
-
- type t = elt list
-
-end
-
-module OASISTypes = struct
-(* # 22 "src/oasis/OASISTypes.ml" *)
-
-
-
-
-
- type name = string
- type package_name = string
- type url = string
- type unix_dirname = string
- type unix_filename = string
- type host_dirname = string
- type host_filename = string
- type prog = string
- type arg = string
- type args = string list
- type command_line = (prog * arg list)
-
-
- type findlib_name = string
- type findlib_full = string
-
-
- type compiled_object =
- | Byte
- | Native
- | Best
-
-
-
- type dependency =
- | FindlibPackage of findlib_full * OASISVersion.comparator option
- | InternalLibrary of name
-
-
-
- type tool =
- | ExternalTool of name
- | InternalExecutable of name
-
-
-
- type vcs =
- | Darcs
- | Git
- | Svn
- | Cvs
- | Hg
- | Bzr
- | Arch
- | Monotone
- | OtherVCS of url
-
-
-
- type plugin_kind =
- [ `Configure
- | `Build
- | `Doc
- | `Test
- | `Install
- | `Extra
- ]
-
-
- type plugin_data_purpose =
- [ `Configure
- | `Build
- | `Install
- | `Clean
- | `Distclean
- | `Install
- | `Uninstall
- | `Test
- | `Doc
- | `Extra
- | `Other of string
- ]
-
-
- type 'a plugin = 'a * name * OASISVersion.t option
-
-
- type all_plugin = plugin_kind plugin
-
-
- type plugin_data = (all_plugin * plugin_data_purpose * (unit -> unit)) list
-
-
-(* # 115 "src/oasis/OASISTypes.ml" *)
-
-
- type 'a conditional = 'a OASISExpr.choices
-
-
- type custom =
- {
- pre_command: (command_line option) conditional;
- post_command: (command_line option) conditional;
- }
-
-
-
- type common_section =
- {
- cs_name: name;
- cs_data: PropList.Data.t;
- cs_plugin_data: plugin_data;
- }
-
-
-
- type build_section =
- {
- bs_build: bool conditional;
- bs_install: bool conditional;
- bs_path: unix_dirname;
- bs_compiled_object: compiled_object;
- bs_build_depends: dependency list;
- bs_build_tools: tool list;
- bs_c_sources: unix_filename list;
- bs_data_files: (unix_filename * unix_filename option) list;
- bs_ccopt: args conditional;
- bs_cclib: args conditional;
- bs_dlllib: args conditional;
- bs_dllpath: args conditional;
- bs_byteopt: args conditional;
- bs_nativeopt: args conditional;
- }
-
-
-
- type library =
- {
- lib_modules: string list;
- lib_pack: bool;
- lib_internal_modules: string list;
- lib_findlib_parent: findlib_name option;
- lib_findlib_name: findlib_name option;
- lib_findlib_containers: findlib_name list;
- }
-
-
- type object_ =
- {
- obj_modules: string list;
- obj_findlib_fullname: findlib_name list option;
- }
-
-
- type executable =
- {
- exec_custom: bool;
- exec_main_is: unix_filename;
- }
-
-
- type flag =
- {
- flag_description: string option;
- flag_default: bool conditional;
- }
-
-
- type source_repository =
- {
- src_repo_type: vcs;
- src_repo_location: url;
- src_repo_browser: url option;
- src_repo_module: string option;
- src_repo_branch: string option;
- src_repo_tag: string option;
- src_repo_subdir: unix_filename option;
- }
-
-
- type test =
- {
- test_type: [`Test] plugin;
- test_command: command_line conditional;
- test_custom: custom;
- test_working_directory: unix_filename option;
- test_run: bool conditional;
- test_tools: tool list;
- }
-
-
- type doc_format =
- | HTML of unix_filename
- | DocText
- | PDF
- | PostScript
- | Info of unix_filename
- | DVI
- | OtherDoc
-
-
-
- type doc =
- {
- doc_type: [`Doc] plugin;
- doc_custom: custom;
- doc_build: bool conditional;
- doc_install: bool conditional;
- doc_install_dir: unix_filename;
- doc_title: string;
- doc_authors: string list;
- doc_abstract: string option;
- doc_format: doc_format;
- doc_data_files: (unix_filename * unix_filename option) list;
- doc_build_tools: tool list;
- }
-
-
- type section =
- | Library of common_section * build_section * library
- | Object of common_section * build_section * object_
- | Executable of common_section * build_section * executable
- | Flag of common_section * flag
- | SrcRepo of common_section * source_repository
- | Test of common_section * test
- | Doc of common_section * doc
-
-
-
- type section_kind =
- [ `Library | `Object | `Executable | `Flag | `SrcRepo | `Test | `Doc ]
-
-
- type package =
- {
- oasis_version: OASISVersion.t;
- ocaml_version: OASISVersion.comparator option;
- findlib_version: OASISVersion.comparator option;
- alpha_features: string list;
- beta_features: string list;
- name: package_name;
- version: OASISVersion.t;
- license: OASISLicense.t;
- license_file: unix_filename option;
- copyrights: string list;
- maintainers: string list;
- authors: string list;
- homepage: url option;
- synopsis: string;
- description: OASISText.t option;
- categories: url list;
-
- conf_type: [`Configure] plugin;
- conf_custom: custom;
-
- build_type: [`Build] plugin;
- build_custom: custom;
-
- install_type: [`Install] plugin;
- install_custom: custom;
- uninstall_custom: custom;
-
- clean_custom: custom;
- distclean_custom: custom;
-
- files_ab: unix_filename list;
- sections: section list;
- plugins: [`Extra] plugin list;
- disable_oasis_section: unix_filename list;
- schema_data: PropList.Data.t;
- plugin_data: plugin_data;
- }
-
-
-end
-
-module OASISFeatures = struct
-(* # 22 "src/oasis/OASISFeatures.ml" *)
-
- open OASISTypes
- open OASISUtils
- open OASISGettext
- open OASISVersion
-
- module MapPlugin =
- Map.Make
- (struct
- type t = plugin_kind * name
- let compare = Pervasives.compare
- end)
-
- module Data =
- struct
- type t =
- {
- oasis_version: OASISVersion.t;
- plugin_versions: OASISVersion.t option MapPlugin.t;
- alpha_features: string list;
- beta_features: string list;
- }
-
- let create oasis_version alpha_features beta_features =
- {
- oasis_version = oasis_version;
- plugin_versions = MapPlugin.empty;
- alpha_features = alpha_features;
- beta_features = beta_features
- }
-
- let of_package pkg =
- create
- pkg.OASISTypes.oasis_version
- pkg.OASISTypes.alpha_features
- pkg.OASISTypes.beta_features
-
- let add_plugin (plugin_kind, plugin_name, plugin_version) t =
- {t with
- plugin_versions = MapPlugin.add
- (plugin_kind, plugin_name)
- plugin_version
- t.plugin_versions}
-
- let plugin_version plugin_kind plugin_name t =
- MapPlugin.find (plugin_kind, plugin_name) t.plugin_versions
-
- let to_string t =
- Printf.sprintf
- "oasis_version: %s; alpha_features: %s; beta_features: %s; \
- plugins_version: %s"
- (OASISVersion.string_of_version t.oasis_version)
- (String.concat ", " t.alpha_features)
- (String.concat ", " t.beta_features)
- (String.concat ", "
- (MapPlugin.fold
- (fun (_, plg) ver_opt acc ->
- (plg^
- (match ver_opt with
- | Some v ->
- " "^(OASISVersion.string_of_version v)
- | None -> ""))
- :: acc)
- t.plugin_versions []))
- end
-
- type origin =
- | Field of string * string
- | Section of string
- | NoOrigin
-
- type stage = Alpha | Beta
-
-
- let string_of_stage =
- function
- | Alpha -> "alpha"
- | Beta -> "beta"
-
-
- let field_of_stage =
- function
- | Alpha -> "AlphaFeatures"
- | Beta -> "BetaFeatures"
-
- type publication = InDev of stage | SinceVersion of OASISVersion.t
-
- type t =
- {
- name: string;
- plugin: all_plugin option;
- publication: publication;
- description: unit -> string;
- }
-
- (* TODO: mutex protect this. *)
- let all_features = Hashtbl.create 13
-
-
- let since_version ver_str = SinceVersion (version_of_string ver_str)
- let alpha = InDev Alpha
- let beta = InDev Beta
-
-
- let to_string t =
- Printf.sprintf
- "feature: %s; plugin: %s; publication: %s"
- t.name
- (match t.plugin with
- | None -> ""
- | Some (_, nm, _) -> nm)
- (match t.publication with
- | InDev stage -> string_of_stage stage
- | SinceVersion ver -> ">= "^(OASISVersion.string_of_version ver))
-
- let data_check t data origin =
- let no_message = "no message" in
-
- let check_feature features stage =
- let has_feature = List.mem t.name features in
- if not has_feature then
- match origin with
- | Field (fld, where) ->
- Some
- (Printf.sprintf
- (f_ "Field %s in %s is only available when feature %s \
- is in field %s.")
- fld where t.name (field_of_stage stage))
- | Section sct ->
- Some
- (Printf.sprintf
- (f_ "Section %s is only available when features %s \
- is in field %s.")
- sct t.name (field_of_stage stage))
- | NoOrigin ->
- Some no_message
- else
- None
- in
-
- let version_is_good ~min_version version fmt =
- let version_is_good =
- OASISVersion.comparator_apply
- version (OASISVersion.VGreaterEqual min_version)
- in
- Printf.ksprintf
- (fun str ->
- if version_is_good then
- None
- else
- Some str)
- fmt
- in
-
- match origin, t.plugin, t.publication with
- | _, _, InDev Alpha -> check_feature data.Data.alpha_features Alpha
- | _, _, InDev Beta -> check_feature data.Data.beta_features Beta
- | Field(fld, where), None, SinceVersion min_version ->
- version_is_good ~min_version data.Data.oasis_version
- (f_ "Field %s in %s is only valid since OASIS v%s, update \
- OASISFormat field from '%s' to '%s' after checking \
- OASIS changelog.")
- fld where (string_of_version min_version)
- (string_of_version data.Data.oasis_version)
- (string_of_version min_version)
-
- | Field(fld, where), Some(plugin_knd, plugin_name, _),
- SinceVersion min_version ->
- begin
- try
- let plugin_version_current =
- try
- match Data.plugin_version plugin_knd plugin_name data with
- | Some ver -> ver
- | None ->
- failwithf
- (f_ "Field %s in %s is only valid for the OASIS \
- plugin %s since v%s, but no plugin version is \
- defined in the _oasis file, change '%s' to \
- '%s (%s)' in your _oasis file.")
- fld where plugin_name (string_of_version min_version)
- plugin_name
- plugin_name (string_of_version min_version)
- with Not_found ->
- failwithf
- (f_ "Field %s in %s is only valid when the OASIS plugin %s \
- is defined.")
- fld where plugin_name
- in
- version_is_good ~min_version plugin_version_current
- (f_ "Field %s in %s is only valid for the OASIS plugin %s \
- since v%s, update your plugin from '%s (%s)' to \
- '%s (%s)' after checking the plugin's changelog.")
- fld where plugin_name (string_of_version min_version)
- plugin_name (string_of_version plugin_version_current)
- plugin_name (string_of_version min_version)
- with Failure msg ->
- Some msg
- end
-
- | Section sct, None, SinceVersion min_version ->
- version_is_good ~min_version data.Data.oasis_version
- (f_ "Section %s is only valid for since OASIS v%s, update \
- OASISFormat field from '%s' to '%s' after checking OASIS \
- changelog.")
- sct (string_of_version min_version)
- (string_of_version data.Data.oasis_version)
- (string_of_version min_version)
-
- | Section sct, Some(plugin_knd, plugin_name, _),
- SinceVersion min_version ->
- begin
- try
- let plugin_version_current =
- try
- match Data.plugin_version plugin_knd plugin_name data with
- | Some ver -> ver
- | None ->
- failwithf
- (f_ "Section %s is only valid for the OASIS \
- plugin %s since v%s, but no plugin version is \
- defined in the _oasis file, change '%s' to \
- '%s (%s)' in your _oasis file.")
- sct plugin_name (string_of_version min_version)
- plugin_name
- plugin_name (string_of_version min_version)
- with Not_found ->
- failwithf
- (f_ "Section %s is only valid when the OASIS plugin %s \
- is defined.")
- sct plugin_name
- in
- version_is_good ~min_version plugin_version_current
- (f_ "Section %s is only valid for the OASIS plugin %s \
- since v%s, update your plugin from '%s (%s)' to \
- '%s (%s)' after checking the plugin's changelog.")
- sct plugin_name (string_of_version min_version)
- plugin_name (string_of_version plugin_version_current)
- plugin_name (string_of_version min_version)
- with Failure msg ->
- Some msg
- end
-
- | NoOrigin, None, SinceVersion min_version ->
- version_is_good ~min_version data.Data.oasis_version "%s" no_message
-
- | NoOrigin, Some(plugin_knd, plugin_name, _), SinceVersion min_version ->
- begin
- try
- let plugin_version_current =
- match Data.plugin_version plugin_knd plugin_name data with
- | Some ver -> ver
- | None -> raise Not_found
- in
- version_is_good ~min_version plugin_version_current
- "%s" no_message
- with Not_found ->
- Some no_message
- end
-
-
- let data_assert t data origin =
- match data_check t data origin with
- | None -> ()
- | Some str -> failwith str
-
-
- let data_test t data =
- match data_check t data NoOrigin with
- | None -> true
- | Some str -> false
-
-
- let package_test t pkg =
- data_test t (Data.of_package pkg)
-
-
- let create ?plugin name publication description =
- let () =
- if Hashtbl.mem all_features name then
- failwithf "Feature '%s' is already declared." name
- in
- let t =
- {
- name = name;
- plugin = plugin;
- publication = publication;
- description = description;
- }
- in
- Hashtbl.add all_features name t;
- t
-
-
- let get_stage name =
- try
- (Hashtbl.find all_features name).publication
- with Not_found ->
- failwithf (f_ "Feature %s doesn't exist.") name
-
-
- let list () =
- Hashtbl.fold (fun _ v acc -> v :: acc) all_features []
-
- (*
- * Real flags.
- *)
-
-
- let features =
- create "features_fields"
- (since_version "0.4")
- (fun () ->
- s_ "Enable to experiment not yet official features.")
-
-
- let flag_docs =
- create "flag_docs"
- (since_version "0.3")
- (fun () ->
- s_ "Building docs require '-docs' flag at configure.")
-
-
- let flag_tests =
- create "flag_tests"
- (since_version "0.3")
- (fun () ->
- s_ "Running tests require '-tests' flag at configure.")
-
-
- let pack =
- create "pack"
- (since_version "0.3")
- (fun () ->
- s_ "Allow to create packed library.")
-
-
- let section_object =
- create "section_object" beta
- (fun () ->
- s_ "Implement an object section.")
-
-
- let dynrun_for_release =
- create "dynrun_for_release" alpha
- (fun () ->
- s_ "Make '-setup-update dynamic' suitable for releasing project.")
-
-
- let compiled_setup_ml =
- create "compiled_setup_ml" alpha
- (fun () ->
- s_ "It compiles the setup.ml and speed-up actions done with it.")
-
- let disable_oasis_section =
- create "disable_oasis_section" alpha
- (fun () ->
- s_ "Allows the OASIS section comments and digest to be omitted in \
- generated files.")
-
- let no_automatic_syntax =
- create "no_automatic_syntax" alpha
- (fun () ->
- s_ "Disable the automatic inclusion of -syntax camlp4o for packages \
- that matches the internal heuristic (if a dependency ends with \
- a .syntax or is a well known syntax).")
-end
-
-module OASISUnixPath = struct
-(* # 22 "src/oasis/OASISUnixPath.ml" *)
-
-
- type unix_filename = string
- type unix_dirname = string
-
-
- type host_filename = string
- type host_dirname = string
-
-
- let current_dir_name = "."
-
-
- let parent_dir_name = ".."
-
-
- let is_current_dir fn =
- fn = current_dir_name || fn = ""
-
-
- let concat f1 f2 =
- if is_current_dir f1 then
- f2
- else
- let f1' =
- try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1
- in
- f1'^"/"^f2
-
-
- let make =
- function
- | hd :: tl ->
- List.fold_left
- (fun f p -> concat f p)
- hd
- tl
- | [] ->
- invalid_arg "OASISUnixPath.make"
-
-
- let dirname f =
- try
- String.sub f 0 (String.rindex f '/')
- with Not_found ->
- current_dir_name
-
-
- let basename f =
- try
- let pos_start =
- (String.rindex f '/') + 1
- in
- String.sub f pos_start ((String.length f) - pos_start)
- with Not_found ->
- f
-
-
- let chop_extension f =
- try
- let last_dot =
- String.rindex f '.'
- in
- let sub =
- String.sub f 0 last_dot
- in
- try
- let last_slash =
- String.rindex f '/'
- in
- if last_slash < last_dot then
- sub
- else
- f
- with Not_found ->
- sub
-
- with Not_found ->
- f
-
-
- let capitalize_file f =
- let dir = dirname f in
- let base = basename f in
- concat dir (String.capitalize base)
-
-
- let uncapitalize_file f =
- let dir = dirname f in
- let base = basename f in
- concat dir (String.uncapitalize base)
-
-
-end
-
-module OASISHostPath = struct
-(* # 22 "src/oasis/OASISHostPath.ml" *)
-
-
- open Filename
-
-
- module Unix = OASISUnixPath
-
-
- let make =
- function
- | [] ->
- invalid_arg "OASISHostPath.make"
- | hd :: tl ->
- List.fold_left Filename.concat hd tl
-
-
- let of_unix ufn =
- if Sys.os_type = "Unix" then
- ufn
- else
- make
- (List.map
- (fun p ->
- if p = Unix.current_dir_name then
- current_dir_name
- else if p = Unix.parent_dir_name then
- parent_dir_name
- else
- p)
- (OASISString.nsplit ufn '/'))
-
-
-end
-
-module OASISSection = struct
-(* # 22 "src/oasis/OASISSection.ml" *)
-
-
- open OASISTypes
-
-
- let section_kind_common =
- function
- | Library (cs, _, _) ->
- `Library, cs
- | Object (cs, _, _) ->
- `Object, cs
- | Executable (cs, _, _) ->
- `Executable, cs
- | Flag (cs, _) ->
- `Flag, cs
- | SrcRepo (cs, _) ->
- `SrcRepo, cs
- | Test (cs, _) ->
- `Test, cs
- | Doc (cs, _) ->
- `Doc, cs
-
-
- let section_common sct =
- snd (section_kind_common sct)
-
-
- let section_common_set cs =
- function
- | Library (_, bs, lib) -> Library (cs, bs, lib)
- | Object (_, bs, obj) -> Object (cs, bs, obj)
- | Executable (_, bs, exec) -> Executable (cs, bs, exec)
- | Flag (_, flg) -> Flag (cs, flg)
- | SrcRepo (_, src_repo) -> SrcRepo (cs, src_repo)
- | Test (_, tst) -> Test (cs, tst)
- | Doc (_, doc) -> Doc (cs, doc)
-
-
- (** Key used to identify section
- *)
- let section_id sct =
- let k, cs =
- section_kind_common sct
- in
- k, cs.cs_name
-
-
- let string_of_section sct =
- let k, nm =
- section_id sct
- in
- (match k with
- | `Library -> "library"
- | `Object -> "object"
- | `Executable -> "executable"
- | `Flag -> "flag"
- | `SrcRepo -> "src repository"
- | `Test -> "test"
- | `Doc -> "doc")
- ^" "^nm
-
-
- let section_find id scts =
- List.find
- (fun sct -> id = section_id sct)
- scts
-
-
- module CSection =
- struct
- type t = section
-
- let id = section_id
-
- let compare t1 t2 =
- compare (id t1) (id t2)
-
- let equal t1 t2 =
- (id t1) = (id t2)
-
- let hash t =
- Hashtbl.hash (id t)
- end
-
-
- module MapSection = Map.Make(CSection)
- module SetSection = Set.Make(CSection)
-
-
-end
-
-module OASISBuildSection = struct
-(* # 22 "src/oasis/OASISBuildSection.ml" *)
-
-
-end
-
-module OASISExecutable = struct
-(* # 22 "src/oasis/OASISExecutable.ml" *)
-
-
- open OASISTypes
-
-
- let unix_exec_is (cs, bs, exec) is_native ext_dll suffix_program =
- let dir =
- OASISUnixPath.concat
- bs.bs_path
- (OASISUnixPath.dirname exec.exec_main_is)
- in
- let is_native_exec =
- match bs.bs_compiled_object with
- | Native -> true
- | Best -> is_native ()
- | Byte -> false
- in
-
- OASISUnixPath.concat
- dir
- (cs.cs_name^(suffix_program ())),
-
- if not is_native_exec &&
- not exec.exec_custom &&
- bs.bs_c_sources <> [] then
- Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ()))
- else
- None
-
-
-end
-
-module OASISLibrary = struct
-(* # 22 "src/oasis/OASISLibrary.ml" *)
-
-
- open OASISTypes
- open OASISUtils
- open OASISGettext
- open OASISSection
-
-
- (* Look for a module file, considering capitalization or not. *)
- let find_module source_file_exists bs modul =
- let possible_base_fn =
- List.map
- (OASISUnixPath.concat bs.bs_path)
- [modul;
- OASISUnixPath.uncapitalize_file modul;
- OASISUnixPath.capitalize_file modul]
- in
- (* TODO: we should be able to be able to determine the source for every
- * files. Hence we should introduce a Module(source: fn) for the fields
- * Modules and InternalModules
- *)
- List.fold_left
- (fun acc base_fn ->
- match acc with
- | `No_sources _ ->
- begin
- let file_found =
- List.fold_left
- (fun acc ext ->
- if source_file_exists (base_fn^ext) then
- (base_fn^ext) :: acc
- else
- acc)
- []
- [".ml"; ".mli"; ".mll"; ".mly"]
- in
- match file_found with
- | [] ->
- acc
- | lst ->
- `Sources (base_fn, lst)
- end
- | `Sources _ ->
- acc)
- (`No_sources possible_base_fn)
- possible_base_fn
-
-
- let source_unix_files ~ctxt (cs, bs, lib) source_file_exists =
- List.fold_left
- (fun acc modul ->
- match find_module source_file_exists bs modul with
- | `Sources (base_fn, lst) ->
- (base_fn, lst) :: acc
- | `No_sources _ ->
- OASISMessage.warning
- ~ctxt
- (f_ "Cannot find source file matching \
- module '%s' in library %s")
- modul cs.cs_name;
- acc)
- []
- (lib.lib_modules @ lib.lib_internal_modules)
-
-
- let generated_unix_files
- ~ctxt
- ~is_native
- ~has_native_dynlink
- ~ext_lib
- ~ext_dll
- ~source_file_exists
- (cs, bs, lib) =
-
- let find_modules lst ext =
- let find_module modul =
- match find_module source_file_exists bs modul with
- | `Sources (base_fn, [fn]) when ext <> "cmi"
- && Filename.check_suffix fn ".mli" ->
- None (* No implementation files for pure interface. *)
- | `Sources (base_fn, _) ->
- Some [base_fn]
- | `No_sources lst ->
- OASISMessage.warning
- ~ctxt
- (f_ "Cannot find source file matching \
- module '%s' in library %s")
- modul cs.cs_name;
- Some lst
- in
- List.fold_left
- (fun acc nm ->
- match find_module nm with
- | None -> acc
- | Some base_fns ->
- List.map (fun base_fn -> base_fn ^"."^ext) base_fns :: acc)
- []
- lst
- in
-
- (* The .cmx that be compiled along *)
- let cmxs =
- let should_be_built =
- match bs.bs_compiled_object with
- | Native -> true
- | Best -> is_native
- | Byte -> false
- in
- if should_be_built then
- if lib.lib_pack then
- find_modules
- [cs.cs_name]
- "cmx"
- else
- find_modules
- (lib.lib_modules @ lib.lib_internal_modules)
- "cmx"
- else
- []
- in
-
- let acc_nopath =
- []
- in
-
- (* The headers and annot/cmt files that should be compiled along *)
- let headers =
- let sufx =
- if lib.lib_pack
- then [".cmti"; ".cmt"; ".annot"]
- else [".cmi"; ".cmti"; ".cmt"; ".annot"]
- in
- List.map
- begin
- List.fold_left
- begin fun accu s ->
- let dot = String.rindex s '.' in
- let base = String.sub s 0 dot in
- List.map ((^) base) sufx @ accu
- end
- []
- end
- (find_modules lib.lib_modules "cmi")
- in
-
- (* Compute what libraries should be built *)
- let acc_nopath =
- (* Add the packed header file if required *)
- let add_pack_header acc =
- if lib.lib_pack then
- [cs.cs_name^".cmi"; cs.cs_name^".cmti"; cs.cs_name^".cmt"] :: acc
- else
- acc
- in
- let byte acc =
- add_pack_header ([cs.cs_name^".cma"] :: acc)
- in
- let native acc =
- let acc =
- add_pack_header
- (if has_native_dynlink then
- [cs.cs_name^".cmxs"] :: acc
- else acc)
- in
- [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc
- in
- match bs.bs_compiled_object with
- | Native ->
- byte (native acc_nopath)
- | Best when is_native ->
- byte (native acc_nopath)
- | Byte | Best ->
- byte acc_nopath
- in
-
- (* Add C library to be built *)
- let acc_nopath =
- if bs.bs_c_sources <> [] then
- begin
- ["lib"^cs.cs_name^"_stubs"^ext_lib]
- ::
- ["dll"^cs.cs_name^"_stubs"^ext_dll]
- ::
- acc_nopath
- end
- else
- acc_nopath
- in
-
- (* All the files generated *)
- List.rev_append
- (List.rev_map
- (List.rev_map
- (OASISUnixPath.concat bs.bs_path))
- acc_nopath)
- (headers @ cmxs)
-
-
-end
-
-module OASISObject = struct
-(* # 22 "src/oasis/OASISObject.ml" *)
-
-
- open OASISTypes
- open OASISGettext
-
-
- let source_unix_files ~ctxt (cs, bs, obj) source_file_exists =
- List.fold_left
- (fun acc modul ->
- match OASISLibrary.find_module source_file_exists bs modul with
- | `Sources (base_fn, lst) ->
- (base_fn, lst) :: acc
- | `No_sources _ ->
- OASISMessage.warning
- ~ctxt
- (f_ "Cannot find source file matching \
- module '%s' in object %s")
- modul cs.cs_name;
- acc)
- []
- obj.obj_modules
-
-
- let generated_unix_files
- ~ctxt
- ~is_native
- ~source_file_exists
- (cs, bs, obj) =
-
- let find_module ext modul =
- match OASISLibrary.find_module source_file_exists bs modul with
- | `Sources (base_fn, _) -> [base_fn ^ ext]
- | `No_sources lst ->
- OASISMessage.warning
- ~ctxt
- (f_ "Cannot find source file matching \
- module '%s' in object %s")
- modul cs.cs_name ;
- lst
- in
-
- let header, byte, native, c_object, f =
- match obj.obj_modules with
- | [ m ] -> (find_module ".cmi" m,
- find_module ".cmo" m,
- find_module ".cmx" m,
- find_module ".o" m,
- fun x -> x)
- | _ -> ([cs.cs_name ^ ".cmi"],
- [cs.cs_name ^ ".cmo"],
- [cs.cs_name ^ ".cmx"],
- [cs.cs_name ^ ".o"],
- OASISUnixPath.concat bs.bs_path)
- in
- List.map (List.map f) (
- match bs.bs_compiled_object with
- | Native ->
- native :: c_object :: byte :: header :: []
- | Best when is_native ->
- native :: c_object :: byte :: header :: []
- | Byte | Best ->
- byte :: header :: [])
-
-
-end
-
-module OASISFindlib = struct
-(* # 22 "src/oasis/OASISFindlib.ml" *)
-
-
- open OASISTypes
- open OASISUtils
- open OASISGettext
- open OASISSection
-
-
- type library_name = name
- type findlib_part_name = name
- type 'a map_of_findlib_part_name = 'a OASISUtils.MapString.t
-
-
- exception InternalLibraryNotFound of library_name
- exception FindlibPackageNotFound of findlib_name
-
-
- type group_t =
- | Container of findlib_name * group_t list
- | Package of (findlib_name *
- common_section *
- build_section *
- [`Library of library | `Object of object_] *
- group_t list)
-
-
- type data = common_section *
- build_section *
- [`Library of library | `Object of object_]
- type tree =
- | Node of (data option) * (tree MapString.t)
- | Leaf of data
-
-
- let findlib_mapping pkg =
- (* Map from library name to either full findlib name or parts + parent. *)
- let fndlb_parts_of_lib_name =
- let fndlb_parts cs lib =
- let name =
- match lib.lib_findlib_name with
- | Some nm -> nm
- | None -> cs.cs_name
- in
- let name =
- String.concat "." (lib.lib_findlib_containers @ [name])
- in
- name
- in
- List.fold_left
- (fun mp ->
- function
- | Library (cs, _, lib) ->
- begin
- let lib_name = cs.cs_name in
- let fndlb_parts = fndlb_parts cs lib in
- if MapString.mem lib_name mp then
- failwithf
- (f_ "The library name '%s' is used more than once.")
- lib_name;
- match lib.lib_findlib_parent with
- | Some lib_name_parent ->
- MapString.add
- lib_name
- (`Unsolved (lib_name_parent, fndlb_parts))
- mp
- | None ->
- MapString.add
- lib_name
- (`Solved fndlb_parts)
- mp
- end
-
- | Object (cs, _, obj) ->
- begin
- let obj_name = cs.cs_name in
- if MapString.mem obj_name mp then
- failwithf
- (f_ "The object name '%s' is used more than once.")
- obj_name;
- let findlib_full_name = match obj.obj_findlib_fullname with
- | Some ns -> String.concat "." ns
- | None -> obj_name
- in
- MapString.add
- obj_name
- (`Solved findlib_full_name)
- mp
- end
-
- | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ ->
- mp)
- MapString.empty
- pkg.sections
- in
-
- (* Solve the above graph to be only library name to full findlib name. *)
- let fndlb_name_of_lib_name =
- let rec solve visited mp lib_name lib_name_child =
- if SetString.mem lib_name visited then
- failwithf
- (f_ "Library '%s' is involved in a cycle \
- with regard to findlib naming.")
- lib_name;
- let visited = SetString.add lib_name visited in
- try
- match MapString.find lib_name mp with
- | `Solved fndlb_nm ->
- fndlb_nm, mp
- | `Unsolved (lib_nm_parent, post_fndlb_nm) ->
- let pre_fndlb_nm, mp =
- solve visited mp lib_nm_parent lib_name
- in
- let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in
- fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp
- with Not_found ->
- failwithf
- (f_ "Library '%s', which is defined as the findlib parent of \
- library '%s', doesn't exist.")
- lib_name lib_name_child
- in
- let mp =
- MapString.fold
- (fun lib_name status mp ->
- match status with
- | `Solved _ ->
- (* Solved initialy, no need to go further *)
- mp
- | `Unsolved _ ->
- let _, mp = solve SetString.empty mp lib_name "" in
- mp)
- fndlb_parts_of_lib_name
- fndlb_parts_of_lib_name
- in
- MapString.map
- (function
- | `Solved fndlb_nm -> fndlb_nm
- | `Unsolved _ -> assert false)
- mp
- in
-
- (* Convert an internal library name to a findlib name. *)
- let findlib_name_of_library_name lib_nm =
- try
- MapString.find lib_nm fndlb_name_of_lib_name
- with Not_found ->
- raise (InternalLibraryNotFound lib_nm)
- in
-
- (* Add a library to the tree.
- *)
- let add sct mp =
- let fndlb_fullname =
- let cs, _, _ = sct in
- let lib_name = cs.cs_name in
- findlib_name_of_library_name lib_name
- in
- let rec add_children nm_lst (children: tree MapString.t) =
- match nm_lst with
- | (hd :: tl) ->
- begin
- let node =
- try
- add_node tl (MapString.find hd children)
- with Not_found ->
- (* New node *)
- new_node tl
- in
- MapString.add hd node children
- end
- | [] ->
- (* Should not have a nameless library. *)
- assert false
- and add_node tl node =
- if tl = [] then
- begin
- match node with
- | Node (None, children) ->
- Node (Some sct, children)
- | Leaf (cs', _, _) | Node (Some (cs', _, _), _) ->
- (* TODO: allow to merge Package, i.e.
- * archive(byte) = "foo.cma foo_init.cmo"
- *)
- let cs, _, _ = sct in
- failwithf
- (f_ "Library '%s' and '%s' have the same findlib name '%s'")
- cs.cs_name cs'.cs_name fndlb_fullname
- end
- else
- begin
- match node with
- | Leaf data ->
- Node (Some data, add_children tl MapString.empty)
- | Node (data_opt, children) ->
- Node (data_opt, add_children tl children)
- end
- and new_node =
- function
- | [] ->
- Leaf sct
- | hd :: tl ->
- Node (None, MapString.add hd (new_node tl) MapString.empty)
- in
- add_children (OASISString.nsplit fndlb_fullname '.') mp
- in
-
- let rec group_of_tree mp =
- MapString.fold
- (fun nm node acc ->
- let cur =
- match node with
- | Node (Some (cs, bs, lib), children) ->
- Package (nm, cs, bs, lib, group_of_tree children)
- | Node (None, children) ->
- Container (nm, group_of_tree children)
- | Leaf (cs, bs, lib) ->
- Package (nm, cs, bs, lib, [])
- in
- cur :: acc)
- mp []
- in
-
- let group_mp =
- List.fold_left
- (fun mp ->
- function
- | Library (cs, bs, lib) ->
- add (cs, bs, `Library lib) mp
- | Object (cs, bs, obj) ->
- add (cs, bs, `Object obj) mp
- | _ ->
- mp)
- MapString.empty
- pkg.sections
- in
-
- let groups =
- group_of_tree group_mp
- in
-
- let library_name_of_findlib_name =
- lazy begin
- (* Revert findlib_name_of_library_name. *)
- MapString.fold
- (fun k v mp -> MapString.add v k mp)
- fndlb_name_of_lib_name
- MapString.empty
- end
- in
- let library_name_of_findlib_name fndlb_nm =
- try
- MapString.find fndlb_nm (Lazy.force library_name_of_findlib_name)
- with Not_found ->
- raise (FindlibPackageNotFound fndlb_nm)
- in
-
- groups,
- findlib_name_of_library_name,
- library_name_of_findlib_name
-
-
- let findlib_of_group =
- function
- | Container (fndlb_nm, _)
- | Package (fndlb_nm, _, _, _, _) -> fndlb_nm
-
-
- let root_of_group grp =
- let rec root_lib_aux =
- (* We do a DFS in the group. *)
- function
- | Container (_, children) ->
- List.fold_left
- (fun res grp ->
- if res = None then
- root_lib_aux grp
- else
- res)
- None
- children
- | Package (_, cs, bs, lib, _) ->
- Some (cs, bs, lib)
- in
- match root_lib_aux grp with
- | Some res ->
- res
- | None ->
- failwithf
- (f_ "Unable to determine root library of findlib library '%s'")
- (findlib_of_group grp)
-
-
-end
-
-module OASISFlag = struct
-(* # 22 "src/oasis/OASISFlag.ml" *)
-
-
-end
-
-module OASISPackage = struct
-(* # 22 "src/oasis/OASISPackage.ml" *)
-
-
-end
-
-module OASISSourceRepository = struct
-(* # 22 "src/oasis/OASISSourceRepository.ml" *)
-
-
-end
-
-module OASISTest = struct
-(* # 22 "src/oasis/OASISTest.ml" *)
-
-
-end
-
-module OASISDocument = struct
-(* # 22 "src/oasis/OASISDocument.ml" *)
-
-
-end
-
-module OASISExec = struct
-(* # 22 "src/oasis/OASISExec.ml" *)
-
-
- open OASISGettext
- open OASISUtils
- open OASISMessage
-
-
- (* TODO: I don't like this quote, it is there because $(rm) foo expands to
- * 'rm -f' foo...
- *)
- let run ~ctxt ?f_exit_code ?(quote=true) cmd args =
- let cmd =
- if quote then
- if Sys.os_type = "Win32" then
- if String.contains cmd ' ' then
- (* Double the 1st double quote... win32... sigh *)
- "\""^(Filename.quote cmd)
- else
- cmd
- else
- Filename.quote cmd
- else
- cmd
- in
- let cmdline =
- String.concat " " (cmd :: args)
- in
- info ~ctxt (f_ "Running command '%s'") cmdline;
- match f_exit_code, Sys.command cmdline with
- | None, 0 -> ()
- | None, i ->
- failwithf
- (f_ "Command '%s' terminated with error code %d")
- cmdline i
- | Some f, i ->
- f i
-
-
- let run_read_output ~ctxt ?f_exit_code cmd args =
- let fn =
- Filename.temp_file "oasis-" ".txt"
- in
- try
- begin
- let () =
- run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn])
- in
- let chn =
- open_in fn
- in
- let routput =
- ref []
- in
- begin
- try
- while true do
- routput := (input_line chn) :: !routput
- done
- with End_of_file ->
- ()
- end;
- close_in chn;
- Sys.remove fn;
- List.rev !routput
- end
- with e ->
- (try Sys.remove fn with _ -> ());
- raise e
-
-
- let run_read_one_line ~ctxt ?f_exit_code cmd args =
- match run_read_output ~ctxt ?f_exit_code cmd args with
- | [fst] ->
- fst
- | lst ->
- failwithf
- (f_ "Command return unexpected output %S")
- (String.concat "\n" lst)
-end
-
-module OASISFileUtil = struct
-(* # 22 "src/oasis/OASISFileUtil.ml" *)
-
-
- open OASISGettext
-
-
- let file_exists_case fn =
- let dirname = Filename.dirname fn in
- let basename = Filename.basename fn in
- if Sys.file_exists dirname then
- if basename = Filename.current_dir_name then
- true
- else
- List.mem
- basename
- (Array.to_list (Sys.readdir dirname))
- else
- false
-
-
- let find_file ?(case_sensitive=true) paths exts =
-
- (* Cardinal product of two list *)
- let ( * ) lst1 lst2 =
- List.flatten
- (List.map
- (fun a ->
- List.map
- (fun b -> a, b)
- lst2)
- lst1)
- in
-
- let rec combined_paths lst =
- match lst with
- | p1 :: p2 :: tl ->
- let acc =
- (List.map
- (fun (a, b) -> Filename.concat a b)
- (p1 * p2))
- in
- combined_paths (acc :: tl)
- | [e] ->
- e
- | [] ->
- []
- in
-
- let alternatives =
- List.map
- (fun (p, e) ->
- if String.length e > 0 && e.[0] <> '.' then
- p ^ "." ^ e
- else
- p ^ e)
- ((combined_paths paths) * exts)
- in
- List.find (fun file ->
- (if case_sensitive then
- file_exists_case file
- else
- Sys.file_exists file)
- && not (Sys.is_directory file)
- ) alternatives
-
-
- let which ~ctxt prg =
- let path_sep =
- match Sys.os_type with
- | "Win32" ->
- ';'
- | _ ->
- ':'
- in
- let path_lst = OASISString.nsplit (Sys.getenv "PATH") path_sep in
- let exec_ext =
- match Sys.os_type with
- | "Win32" ->
- "" :: (OASISString.nsplit (Sys.getenv "PATHEXT") path_sep)
- | _ ->
- [""]
- in
- find_file ~case_sensitive:false [path_lst; [prg]] exec_ext
-
-
- (**/**)
- let rec fix_dir dn =
- (* Windows hack because Sys.file_exists "src\\" = false when
- * Sys.file_exists "src" = true
- *)
- let ln =
- String.length dn
- in
- if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then
- fix_dir (String.sub dn 0 (ln - 1))
- else
- dn
-
-
- let q = Filename.quote
- (**/**)
-
-
- let cp ~ctxt ?(recurse=false) src tgt =
- if recurse then
- match Sys.os_type with
- | "Win32" ->
- OASISExec.run ~ctxt
- "xcopy" [q src; q tgt; "/E"]
- | _ ->
- OASISExec.run ~ctxt
- "cp" ["-r"; q src; q tgt]
- else
- OASISExec.run ~ctxt
- (match Sys.os_type with
- | "Win32" -> "copy"
- | _ -> "cp")
- [q src; q tgt]
-
-
- let mkdir ~ctxt tgt =
- OASISExec.run ~ctxt
- (match Sys.os_type with
- | "Win32" -> "md"
- | _ -> "mkdir")
- [q tgt]
-
-
- let rec mkdir_parent ~ctxt f tgt =
- let tgt =
- fix_dir tgt
- in
- if Sys.file_exists tgt then
- begin
- if not (Sys.is_directory tgt) then
- OASISUtils.failwithf
- (f_ "Cannot create directory '%s', a file of the same name already \
- exists")
- tgt
- end
- else
- begin
- mkdir_parent ~ctxt f (Filename.dirname tgt);
- if not (Sys.file_exists tgt) then
- begin
- f tgt;
- mkdir ~ctxt tgt
- end
- end
-
-
- let rmdir ~ctxt tgt =
- if Sys.readdir tgt = [||] then begin
- match Sys.os_type with
- | "Win32" ->
- OASISExec.run ~ctxt "rd" [q tgt]
- | _ ->
- OASISExec.run ~ctxt "rm" ["-r"; q tgt]
- end else begin
- OASISMessage.error ~ctxt
- (f_ "Cannot remove directory '%s': not empty.")
- tgt
- end
-
-
- let glob ~ctxt fn =
- let basename =
- Filename.basename fn
- in
- if String.length basename >= 2 &&
- basename.[0] = '*' &&
- basename.[1] = '.' then
- begin
- let ext_len =
- (String.length basename) - 2
- in
- let ext =
- String.sub basename 2 ext_len
- in
- let dirname =
- Filename.dirname fn
- in
- Array.fold_left
- (fun acc fn ->
- try
- let fn_ext =
- String.sub
- fn
- ((String.length fn) - ext_len)
- ext_len
- in
- if fn_ext = ext then
- (Filename.concat dirname fn) :: acc
- else
- acc
- with Invalid_argument _ ->
- acc)
- []
- (Sys.readdir dirname)
- end
- else
- begin
- if file_exists_case fn then
- [fn]
- else
- []
- end
-end
-
-
-# 2893 "setup.ml"
-module BaseEnvLight = struct
-(* # 22 "src/base/BaseEnvLight.ml" *)
-
-
- module MapString = Map.Make(String)
-
-
- type t = string MapString.t
-
-
- let default_filename =
- Filename.concat
- (Sys.getcwd ())
- "setup.data"
-
-
- let load ?(allow_empty=false) ?(filename=default_filename) () =
- if Sys.file_exists filename then
- begin
- let chn =
- open_in_bin filename
- in
- let st =
- Stream.of_channel chn
- in
- let line =
- ref 1
- in
- let st_line =
- Stream.from
- (fun _ ->
- try
- match Stream.next st with
- | '\n' -> incr line; Some '\n'
- | c -> Some c
- with Stream.Failure -> None)
- in
- let lexer =
- Genlex.make_lexer ["="] st_line
- in
- let rec read_file mp =
- match Stream.npeek 3 lexer with
- | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
- Stream.junk lexer;
- Stream.junk lexer;
- Stream.junk lexer;
- read_file (MapString.add nm value mp)
- | [] ->
- mp
- | _ ->
- failwith
- (Printf.sprintf
- "Malformed data file '%s' line %d"
- filename !line)
- in
- let mp =
- read_file MapString.empty
- in
- close_in chn;
- mp
- end
- else if allow_empty then
- begin
- MapString.empty
- end
- else
- begin
- failwith
- (Printf.sprintf
- "Unable to load environment, the file '%s' doesn't exist."
- filename)
- end
-
-
- let rec var_expand str env =
- let buff =
- Buffer.create ((String.length str) * 2)
- in
- Buffer.add_substitute
- buff
- (fun var ->
- try
- var_expand (MapString.find var env) env
- with Not_found ->
- failwith
- (Printf.sprintf
- "No variable %s defined when trying to expand %S."
- var
- str))
- str;
- Buffer.contents buff
-
-
- let var_get name env =
- var_expand (MapString.find name env) env
-
-
- let var_choose lst env =
- OASISExpr.choose
- (fun nm -> var_get nm env)
- lst
-end
-
-
-# 2998 "setup.ml"
-module BaseContext = struct
-(* # 22 "src/base/BaseContext.ml" *)
-
- (* TODO: get rid of this module. *)
- open OASISContext
-
-
- let args () = fst (fspecs ())
-
-
- let default = default
-
-end
-
-module BaseMessage = struct
-(* # 22 "src/base/BaseMessage.ml" *)
-
-
- (** Message to user, overrid for Base
- @author Sylvain Le Gall
- *)
- open OASISMessage
- open BaseContext
-
-
- let debug fmt = debug ~ctxt:!default fmt
-
-
- let info fmt = info ~ctxt:!default fmt
-
-
- let warning fmt = warning ~ctxt:!default fmt
-
-
- let error fmt = error ~ctxt:!default fmt
-
-end
-
-module BaseEnv = struct
-(* # 22 "src/base/BaseEnv.ml" *)
-
- open OASISGettext
- open OASISUtils
- open PropList
-
-
- module MapString = BaseEnvLight.MapString
-
-
- type origin_t =
- | ODefault
- | OGetEnv
- | OFileLoad
- | OCommandLine
-
-
- type cli_handle_t =
- | CLINone
- | CLIAuto
- | CLIWith
- | CLIEnable
- | CLIUser of (Arg.key * Arg.spec * Arg.doc) list
-
-
- type definition_t =
- {
- hide: bool;
- dump: bool;
- cli: cli_handle_t;
- arg_help: string option;
- group: string option;
- }
-
-
- let schema =
- Schema.create "environment"
-
-
- (* Environment data *)
- let env =
- Data.create ()
-
-
- (* Environment data from file *)
- let env_from_file =
- ref MapString.empty
-
-
- (* Lexer for var *)
- let var_lxr =
- Genlex.make_lexer []
-
-
- let rec var_expand str =
- let buff =
- Buffer.create ((String.length str) * 2)
- in
- Buffer.add_substitute
- buff
- (fun var ->
- try
- (* TODO: this is a quick hack to allow calling Test.Command
- * without defining executable name really. I.e. if there is
- * an exec Executable toto, then $(toto) should be replace
- * by its real name. It is however useful to have this function
- * for other variable that depend on the host and should be
- * written better than that.
- *)
- let st =
- var_lxr (Stream.of_string var)
- in
- match Stream.npeek 3 st with
- | [Genlex.Ident "utoh"; Genlex.Ident nm] ->
- OASISHostPath.of_unix (var_get nm)
- | [Genlex.Ident "utoh"; Genlex.String s] ->
- OASISHostPath.of_unix s
- | [Genlex.Ident "ocaml_escaped"; Genlex.Ident nm] ->
- String.escaped (var_get nm)
- | [Genlex.Ident "ocaml_escaped"; Genlex.String s] ->
- String.escaped s
- | [Genlex.Ident nm] ->
- var_get nm
- | _ ->
- failwithf
- (f_ "Unknown expression '%s' in variable expansion of %s.")
- var
- str
- with
- | Unknown_field (_, _) ->
- failwithf
- (f_ "No variable %s defined when trying to expand %S.")
- var
- str
- | Stream.Error e ->
- failwithf
- (f_ "Syntax error when parsing '%s' when trying to \
- expand %S: %s")
- var
- str
- e)
- str;
- Buffer.contents buff
-
-
- and var_get name =
- let vl =
- try
- Schema.get schema env name
- with Unknown_field _ as e ->
- begin
- try
- MapString.find name !env_from_file
- with Not_found ->
- raise e
- end
- in
- var_expand vl
-
-
- let var_choose ?printer ?name lst =
- OASISExpr.choose
- ?printer
- ?name
- var_get
- lst
-
-
- let var_protect vl =
- let buff =
- Buffer.create (String.length vl)
- in
- String.iter
- (function
- | '$' -> Buffer.add_string buff "\\$"
- | c -> Buffer.add_char buff c)
- vl;
- Buffer.contents buff
-
-
- let var_define
- ?(hide=false)
- ?(dump=true)
- ?short_desc
- ?(cli=CLINone)
- ?arg_help
- ?group
- name (* TODO: type constraint on the fact that name must be a valid OCaml
- id *)
- dflt =
-
- let default =
- [
- OFileLoad, (fun () -> MapString.find name !env_from_file);
- ODefault, dflt;
- OGetEnv, (fun () -> Sys.getenv name);
- ]
- in
-
- let extra =
- {
- hide = hide;
- dump = dump;
- cli = cli;
- arg_help = arg_help;
- group = group;
- }
- in
-
- (* Try to find a value that can be defined
- *)
- let var_get_low lst =
- let errors, res =
- List.fold_left
- (fun (errors, res) (o, v) ->
- if res = None then
- begin
- try
- errors, Some (v ())
- with
- | Not_found ->
- errors, res
- | Failure rsn ->
- (rsn :: errors), res
- | e ->
- (Printexc.to_string e) :: errors, res
- end
- else
- errors, res)
- ([], None)
- (List.sort
- (fun (o1, _) (o2, _) ->
- Pervasives.compare o2 o1)
- lst)
- in
- match res, errors with
- | Some v, _ ->
- v
- | None, [] ->
- raise (Not_set (name, None))
- | None, lst ->
- raise (Not_set (name, Some (String.concat (s_ ", ") lst)))
- in
-
- let help =
- match short_desc with
- | Some fs -> Some fs
- | None -> None
- in
-
- let var_get_lst =
- FieldRO.create
- ~schema
- ~name
- ~parse:(fun ?(context=ODefault) s -> [context, fun () -> s])
- ~print:var_get_low
- ~default
- ~update:(fun ?context x old_x -> x @ old_x)
- ?help
- extra
- in
-
- fun () ->
- var_expand (var_get_low (var_get_lst env))
-
-
- let var_redefine
- ?hide
- ?dump
- ?short_desc
- ?cli
- ?arg_help
- ?group
- name
- dflt =
- if Schema.mem schema name then
- begin
- (* TODO: look suspsicious, we want to memorize dflt not dflt () *)
- Schema.set schema env ~context:ODefault name (dflt ());
- fun () -> var_get name
- end
- else
- begin
- var_define
- ?hide
- ?dump
- ?short_desc
- ?cli
- ?arg_help
- ?group
- name
- dflt
- end
-
-
- let var_ignore (e: unit -> string) = ()
-
-
- let print_hidden =
- var_define
- ~hide:true
- ~dump:false
- ~cli:CLIAuto
- ~arg_help:"Print even non-printable variable. (debug)"
- "print_hidden"
- (fun () -> "false")
-
-
- let var_all () =
- List.rev
- (Schema.fold
- (fun acc nm def _ ->
- if not def.hide || bool_of_string (print_hidden ()) then
- nm :: acc
- else
- acc)
- []
- schema)
-
-
- let default_filename =
- BaseEnvLight.default_filename
-
-
- let load ?allow_empty ?filename () =
- env_from_file := BaseEnvLight.load ?allow_empty ?filename ()
-
-
- let unload () =
- env_from_file := MapString.empty;
- Data.clear env
-
-
- let dump ?(filename=default_filename) () =
- let chn =
- open_out_bin filename
- in
- let output nm value =
- Printf.fprintf chn "%s=%S\n" nm value
- in
- let mp_todo =
- (* Dump data from schema *)
- Schema.fold
- (fun mp_todo nm def _ ->
- if def.dump then
- begin
- try
- let value =
- Schema.get
- schema
- env
- nm
- in
- output nm value
- with Not_set _ ->
- ()
- end;
- MapString.remove nm mp_todo)
- !env_from_file
- schema
- in
- (* Dump data defined outside of schema *)
- MapString.iter output mp_todo;
-
- (* End of the dump *)
- close_out chn
-
-
- let print () =
- let printable_vars =
- Schema.fold
- (fun acc nm def short_descr_opt ->
- if not def.hide || bool_of_string (print_hidden ()) then
- begin
- try
- let value =
- Schema.get
- schema
- env
- nm
- in
- let txt =
- match short_descr_opt with
- | Some s -> s ()
- | None -> nm
- in
- (txt, value) :: acc
- with Not_set _ ->
- acc
- end
- else
- acc)
- []
- schema
- in
- let max_length =
- List.fold_left max 0
- (List.rev_map String.length
- (List.rev_map fst printable_vars))
- in
- let dot_pad str =
- String.make ((max_length - (String.length str)) + 3) '.'
- in
-
- Printf.printf "\nConfiguration: \n";
- List.iter
- (fun (name, value) ->
- Printf.printf "%s: %s %s\n" name (dot_pad name) value)
- (List.rev printable_vars);
- Printf.printf "\n%!"
-
-
- let args () =
- let arg_concat =
- OASISUtils.varname_concat ~hyphen:'-'
- in
- [
- "--override",
- Arg.Tuple
- (
- let rvr = ref ""
- in
- let rvl = ref ""
- in
- [
- Arg.Set_string rvr;
- Arg.Set_string rvl;
- Arg.Unit
- (fun () ->
- Schema.set
- schema
- env
- ~context:OCommandLine
- !rvr
- !rvl)
- ]
- ),
- "var+val Override any configuration variable.";
-
- ]
- @
- List.flatten
- (Schema.fold
- (fun acc name def short_descr_opt ->
- let var_set s =
- Schema.set
- schema
- env
- ~context:OCommandLine
- name
- s
- in
-
- let arg_name =
- OASISUtils.varname_of_string ~hyphen:'-' name
- in
-
- let hlp =
- match short_descr_opt with
- | Some txt -> txt ()
- | None -> ""
- in
-
- let arg_hlp =
- match def.arg_help with
- | Some s -> s
- | None -> "str"
- in
-
- let default_value =
- try
- Printf.sprintf
- (f_ " [%s]")
- (Schema.get
- schema
- env
- name)
- with Not_set _ ->
- ""
- in
-
- let args =
- match def.cli with
- | CLINone ->
- []
- | CLIAuto ->
- [
- arg_concat "--" arg_name,
- Arg.String var_set,
- Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
- ]
- | CLIWith ->
- [
- arg_concat "--with-" arg_name,
- Arg.String var_set,
- Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
- ]
- | CLIEnable ->
- let dflt =
- if default_value = " [true]" then
- s_ " [default: enabled]"
- else
- s_ " [default: disabled]"
- in
- [
- arg_concat "--enable-" arg_name,
- Arg.Unit (fun () -> var_set "true"),
- Printf.sprintf (f_ " %s%s") hlp dflt;
-
- arg_concat "--disable-" arg_name,
- Arg.Unit (fun () -> var_set "false"),
- Printf.sprintf (f_ " %s%s") hlp dflt
- ]
- | CLIUser lst ->
- lst
- in
- args :: acc)
- []
- schema)
-end
-
-module BaseArgExt = struct
-(* # 22 "src/base/BaseArgExt.ml" *)
-
-
- open OASISUtils
- open OASISGettext
-
-
- let parse argv args =
- (* Simulate command line for Arg *)
- let current =
- ref 0
- in
-
- try
- Arg.parse_argv
- ~current:current
- (Array.concat [[|"none"|]; argv])
- (Arg.align args)
- (failwithf (f_ "Don't know what to do with arguments: '%s'"))
- (s_ "configure options:")
- with
- | Arg.Help txt ->
- print_endline txt;
- exit 0
- | Arg.Bad txt ->
- prerr_endline txt;
- exit 1
-end
-
-module BaseCheck = struct
-(* # 22 "src/base/BaseCheck.ml" *)
-
-
- open BaseEnv
- open BaseMessage
- open OASISUtils
- open OASISGettext
-
-
- let prog_best prg prg_lst =
- var_redefine
- prg
- (fun () ->
- let alternate =
- List.fold_left
- (fun res e ->
- match res with
- | Some _ ->
- res
- | None ->
- try
- Some (OASISFileUtil.which ~ctxt:!BaseContext.default e)
- with Not_found ->
- None)
- None
- prg_lst
- in
- match alternate with
- | Some prg -> prg
- | None -> raise Not_found)
-
-
- let prog prg =
- prog_best prg [prg]
-
-
- let prog_opt prg =
- prog_best prg [prg^".opt"; prg]
-
-
- let ocamlfind =
- prog "ocamlfind"
-
-
- let version
- var_prefix
- cmp
- fversion
- () =
- (* Really compare version provided *)
- let var =
- var_prefix^"_version_"^(OASISVersion.varname_of_comparator cmp)
- in
- var_redefine
- ~hide:true
- var
- (fun () ->
- let version_str =
- match fversion () with
- | "[Distributed with OCaml]" ->
- begin
- try
- (var_get "ocaml_version")
- with Not_found ->
- warning
- (f_ "Variable ocaml_version not defined, fallback \
- to default");
- Sys.ocaml_version
- end
- | res ->
- res
- in
- let version =
- OASISVersion.version_of_string version_str
- in
- if OASISVersion.comparator_apply version cmp then
- version_str
- else
- failwithf
- (f_ "Cannot satisfy version constraint on %s: %s (version: %s)")
- var_prefix
- (OASISVersion.string_of_comparator cmp)
- version_str)
- ()
-
-
- let package_version pkg =
- OASISExec.run_read_one_line ~ctxt:!BaseContext.default
- (ocamlfind ())
- ["query"; "-format"; "%v"; pkg]
-
-
- let package ?version_comparator pkg () =
- let var =
- OASISUtils.varname_concat
- "pkg_"
- (OASISUtils.varname_of_string pkg)
- in
- let findlib_dir pkg =
- let dir =
- OASISExec.run_read_one_line ~ctxt:!BaseContext.default
- (ocamlfind ())
- ["query"; "-format"; "%d"; pkg]
- in
- if Sys.file_exists dir && Sys.is_directory dir then
- dir
- else
- failwithf
- (f_ "When looking for findlib package %s, \
- directory %s return doesn't exist")
- pkg dir
- in
- let vl =
- var_redefine
- var
- (fun () -> findlib_dir pkg)
- ()
- in
- (
- match version_comparator with
- | Some ver_cmp ->
- ignore
- (version
- var
- ver_cmp
- (fun _ -> package_version pkg)
- ())
- | None ->
- ()
- );
- vl
-end
-
-module BaseOCamlcConfig = struct
-(* # 22 "src/base/BaseOCamlcConfig.ml" *)
-
-
- open BaseEnv
- open OASISUtils
- open OASISGettext
-
-
- module SMap = Map.Make(String)
-
-
- let ocamlc =
- BaseCheck.prog_opt "ocamlc"
-
-
- let ocamlc_config_map =
- (* Map name to value for ocamlc -config output
- (name ^": "^value)
- *)
- let rec split_field mp lst =
- match lst with
- | line :: tl ->
- let mp =
- try
- let pos_semicolon =
- String.index line ':'
- in
- if pos_semicolon > 1 then
- (
- let name =
- String.sub line 0 pos_semicolon
- in
- let linelen =
- String.length line
- in
- let value =
- if linelen > pos_semicolon + 2 then
- String.sub
- line
- (pos_semicolon + 2)
- (linelen - pos_semicolon - 2)
- else
- ""
- in
- SMap.add name value mp
- )
- else
- (
- mp
- )
- with Not_found ->
- (
- mp
- )
- in
- split_field mp tl
- | [] ->
- mp
- in
-
- let cache =
- lazy
- (var_protect
- (Marshal.to_string
- (split_field
- SMap.empty
- (OASISExec.run_read_output
- ~ctxt:!BaseContext.default
- (ocamlc ()) ["-config"]))
- []))
- in
- var_redefine
- "ocamlc_config_map"
- ~hide:true
- ~dump:false
- (fun () ->
- (* TODO: update if ocamlc change !!! *)
- Lazy.force cache)
-
-
- let var_define nm =
- (* Extract data from ocamlc -config *)
- let avlbl_config_get () =
- Marshal.from_string
- (ocamlc_config_map ())
- 0
- in
- let chop_version_suffix s =
- try
- String.sub s 0 (String.index s '+')
- with _ ->
- s
- in
-
- let nm_config, value_config =
- match nm with
- | "ocaml_version" ->
- "version", chop_version_suffix
- | _ -> nm, (fun x -> x)
- in
- var_redefine
- nm
- (fun () ->
- try
- let map =
- avlbl_config_get ()
- in
- let value =
- SMap.find nm_config map
- in
- value_config value
- with Not_found ->
- failwithf
- (f_ "Cannot find field '%s' in '%s -config' output")
- nm
- (ocamlc ()))
-
-end
-
-module BaseStandardVar = struct
-(* # 22 "src/base/BaseStandardVar.ml" *)
-
-
- open OASISGettext
- open OASISTypes
- open OASISExpr
- open BaseCheck
- open BaseEnv
-
-
- let ocamlfind = BaseCheck.ocamlfind
- let ocamlc = BaseOCamlcConfig.ocamlc
- let ocamlopt = prog_opt "ocamlopt"
- let ocamlbuild = prog "ocamlbuild"
-
-
- (**/**)
- let rpkg =
- ref None
-
-
- let pkg_get () =
- match !rpkg with
- | Some pkg -> pkg
- | None -> failwith (s_ "OASIS Package is not set")
-
-
- let var_cond = ref []
-
-
- let var_define_cond ~since_version f dflt =
- let holder = ref (fun () -> dflt) in
- let since_version =
- OASISVersion.VGreaterEqual (OASISVersion.version_of_string since_version)
- in
- var_cond :=
- (fun ver ->
- if OASISVersion.comparator_apply ver since_version then
- holder := f ()) :: !var_cond;
- fun () -> !holder ()
-
-
- (**/**)
-
-
- let pkg_name =
- var_define
- ~short_desc:(fun () -> s_ "Package name")
- "pkg_name"
- (fun () -> (pkg_get ()).name)
-
-
- let pkg_version =
- var_define
- ~short_desc:(fun () -> s_ "Package version")
- "pkg_version"
- (fun () ->
- (OASISVersion.string_of_version (pkg_get ()).version))
-
-
- let c = BaseOCamlcConfig.var_define
-
-
- let os_type = c "os_type"
- let system = c "system"
- let architecture = c "architecture"
- let ccomp_type = c "ccomp_type"
- let ocaml_version = c "ocaml_version"
-
-
- (* TODO: Check standard variable presence at runtime *)
-
-
- let standard_library_default = c "standard_library_default"
- let standard_library = c "standard_library"
- let standard_runtime = c "standard_runtime"
- let bytecomp_c_compiler = c "bytecomp_c_compiler"
- let native_c_compiler = c "native_c_compiler"
- let model = c "model"
- let ext_obj = c "ext_obj"
- let ext_asm = c "ext_asm"
- let ext_lib = c "ext_lib"
- let ext_dll = c "ext_dll"
- let default_executable_name = c "default_executable_name"
- let systhread_supported = c "systhread_supported"
-
-
- let flexlink =
- BaseCheck.prog "flexlink"
-
-
- let flexdll_version =
- var_define
- ~short_desc:(fun () -> "FlexDLL version (Win32)")
- "flexdll_version"
- (fun () ->
- let lst =
- OASISExec.run_read_output ~ctxt:!BaseContext.default
- (flexlink ()) ["-help"]
- in
- match lst with
- | line :: _ ->
- Scanf.sscanf line "FlexDLL version %s" (fun ver -> ver)
- | [] ->
- raise Not_found)
-
-
- (**/**)
- let p name hlp dflt =
- var_define
- ~short_desc:hlp
- ~cli:CLIAuto
- ~arg_help:"dir"
- name
- dflt
-
-
- let (/) a b =
- if os_type () = Sys.os_type then
- Filename.concat a b
- else if os_type () = "Unix" then
- OASISUnixPath.concat a b
- else
- OASISUtils.failwithf (f_ "Cannot handle os_type %s filename concat")
- (os_type ())
- (**/**)
-
-
- let prefix =
- p "prefix"
- (fun () -> s_ "Install architecture-independent files dir")
- (fun () ->
- match os_type () with
- | "Win32" ->
- let program_files =
- Sys.getenv "PROGRAMFILES"
- in
- program_files/(pkg_name ())
- | _ ->
- "/usr/local")
-
-
- let exec_prefix =
- p "exec_prefix"
- (fun () -> s_ "Install architecture-dependent files in dir")
- (fun () -> "$prefix")
-
-
- let bindir =
- p "bindir"
- (fun () -> s_ "User executables")
- (fun () -> "$exec_prefix"/"bin")
-
-
- let sbindir =
- p "sbindir"
- (fun () -> s_ "System admin executables")
- (fun () -> "$exec_prefix"/"sbin")
-
-
- let libexecdir =
- p "libexecdir"
- (fun () -> s_ "Program executables")
- (fun () -> "$exec_prefix"/"libexec")
-
-
- let sysconfdir =
- p "sysconfdir"
- (fun () -> s_ "Read-only single-machine data")
- (fun () -> "$prefix"/"etc")
-
-
- let sharedstatedir =
- p "sharedstatedir"
- (fun () -> s_ "Modifiable architecture-independent data")
- (fun () -> "$prefix"/"com")
-
-
- let localstatedir =
- p "localstatedir"
- (fun () -> s_ "Modifiable single-machine data")
- (fun () -> "$prefix"/"var")
-
-
- let libdir =
- p "libdir"
- (fun () -> s_ "Object code libraries")
- (fun () -> "$exec_prefix"/"lib")
-
-
- let datarootdir =
- p "datarootdir"
- (fun () -> s_ "Read-only arch-independent data root")
- (fun () -> "$prefix"/"share")
-
-
- let datadir =
- p "datadir"
- (fun () -> s_ "Read-only architecture-independent data")
- (fun () -> "$datarootdir")
-
-
- let infodir =
- p "infodir"
- (fun () -> s_ "Info documentation")
- (fun () -> "$datarootdir"/"info")
-
-
- let localedir =
- p "localedir"
- (fun () -> s_ "Locale-dependent data")
- (fun () -> "$datarootdir"/"locale")
-
-
- let mandir =
- p "mandir"
- (fun () -> s_ "Man documentation")
- (fun () -> "$datarootdir"/"man")
-
-
- let docdir =
- p "docdir"
- (fun () -> s_ "Documentation root")
- (fun () -> "$datarootdir"/"doc"/"$pkg_name")
-
-
- let htmldir =
- p "htmldir"
- (fun () -> s_ "HTML documentation")
- (fun () -> "$docdir")
-
-
- let dvidir =
- p "dvidir"
- (fun () -> s_ "DVI documentation")
- (fun () -> "$docdir")
-
-
- let pdfdir =
- p "pdfdir"
- (fun () -> s_ "PDF documentation")
- (fun () -> "$docdir")
-
-
- let psdir =
- p "psdir"
- (fun () -> s_ "PS documentation")
- (fun () -> "$docdir")
-
-
- let destdir =
- p "destdir"
- (fun () -> s_ "Prepend a path when installing package")
- (fun () ->
- raise
- (PropList.Not_set
- ("destdir",
- Some (s_ "undefined by construct"))))
-
-
- let findlib_version =
- var_define
- "findlib_version"
- (fun () ->
- BaseCheck.package_version "findlib")
-
-
- let is_native =
- var_define
- "is_native"
- (fun () ->
- try
- let _s: string =
- ocamlopt ()
- in
- "true"
- with PropList.Not_set _ ->
- let _s: string =
- ocamlc ()
- in
- "false")
-
-
- let ext_program =
- var_define
- "suffix_program"
- (fun () ->
- match os_type () with
- | "Win32" | "Cygwin" -> ".exe"
- | _ -> "")
-
-
- let rm =
- var_define
- ~short_desc:(fun () -> s_ "Remove a file.")
- "rm"
- (fun () ->
- match os_type () with
- | "Win32" -> "del"
- | _ -> "rm -f")
-
-
- let rmdir =
- var_define
- ~short_desc:(fun () -> s_ "Remove a directory.")
- "rmdir"
- (fun () ->
- match os_type () with
- | "Win32" -> "rd"
- | _ -> "rm -rf")
-
-
- let debug =
- var_define
- ~short_desc:(fun () -> s_ "Turn ocaml debug flag on")
- ~cli:CLIEnable
- "debug"
- (fun () -> "true")
-
-
- let profile =
- var_define
- ~short_desc:(fun () -> s_ "Turn ocaml profile flag on")
- ~cli:CLIEnable
- "profile"
- (fun () -> "false")
-
-
- let tests =
- var_define_cond ~since_version:"0.3"
- (fun () ->
- var_define
- ~short_desc:(fun () ->
- s_ "Compile tests executable and library and run them")
- ~cli:CLIEnable
- "tests"
- (fun () -> "false"))
- "true"
-
-
- let docs =
- var_define_cond ~since_version:"0.3"
- (fun () ->
- var_define
- ~short_desc:(fun () -> s_ "Create documentations")
- ~cli:CLIEnable
- "docs"
- (fun () -> "true"))
- "true"
-
-
- let native_dynlink =
- var_define
- ~short_desc:(fun () -> s_ "Compiler support generation of .cmxs.")
- ~cli:CLINone
- "native_dynlink"
- (fun () ->
- let res =
- let ocaml_lt_312 () =
- OASISVersion.comparator_apply
- (OASISVersion.version_of_string (ocaml_version ()))
- (OASISVersion.VLesser
- (OASISVersion.version_of_string "3.12.0"))
- in
- let flexdll_lt_030 () =
- OASISVersion.comparator_apply
- (OASISVersion.version_of_string (flexdll_version ()))
- (OASISVersion.VLesser
- (OASISVersion.version_of_string "0.30"))
- in
- let has_native_dynlink =
- let ocamlfind = ocamlfind () in
- try
- let fn =
- OASISExec.run_read_one_line
- ~ctxt:!BaseContext.default
- ocamlfind
- ["query"; "-predicates"; "native"; "dynlink";
- "-format"; "%d/%a"]
- in
- Sys.file_exists fn
- with _ ->
- false
- in
- if not has_native_dynlink then
- false
- else if ocaml_lt_312 () then
- false
- else if (os_type () = "Win32" || os_type () = "Cygwin")
- && flexdll_lt_030 () then
- begin
- BaseMessage.warning
- (f_ ".cmxs generation disabled because FlexDLL needs to be \
- at least 0.30. Please upgrade FlexDLL from %s to 0.30.")
- (flexdll_version ());
- false
- end
- else
- true
- in
- string_of_bool res)
-
-
- let init pkg =
- rpkg := Some pkg;
- List.iter (fun f -> f pkg.oasis_version) !var_cond
-
-end
-
-module BaseFileAB = struct
-(* # 22 "src/base/BaseFileAB.ml" *)
-
-
- open BaseEnv
- open OASISGettext
- open BaseMessage
-
-
- let to_filename fn =
- let fn =
- OASISHostPath.of_unix fn
- in
- if not (Filename.check_suffix fn ".ab") then
- warning
- (f_ "File '%s' doesn't have '.ab' extension")
- fn;
- Filename.chop_extension fn
-
-
- let replace fn_lst =
- let buff =
- Buffer.create 13
- in
- List.iter
- (fun fn ->
- let fn =
- OASISHostPath.of_unix fn
- in
- let chn_in =
- open_in fn
- in
- let chn_out =
- open_out (to_filename fn)
- in
- (
- try
- while true do
- Buffer.add_string buff (var_expand (input_line chn_in));
- Buffer.add_char buff '\n'
- done
- with End_of_file ->
- ()
- );
- Buffer.output_buffer chn_out buff;
- Buffer.clear buff;
- close_in chn_in;
- close_out chn_out)
- fn_lst
-end
-
-module BaseLog = struct
-(* # 22 "src/base/BaseLog.ml" *)
-
-
- open OASISUtils
-
-
- let default_filename =
- Filename.concat
- (Filename.dirname BaseEnv.default_filename)
- "setup.log"
-
-
- module SetTupleString =
- Set.Make
- (struct
- type t = string * string
- let compare (s11, s12) (s21, s22) =
- match String.compare s11 s21 with
- | 0 -> String.compare s12 s22
- | n -> n
- end)
-
-
- let load () =
- if Sys.file_exists default_filename then
- begin
- let chn =
- open_in default_filename
- in
- let scbuf =
- Scanf.Scanning.from_file default_filename
- in
- let rec read_aux (st, lst) =
- if not (Scanf.Scanning.end_of_input scbuf) then
- begin
- let acc =
- try
- Scanf.bscanf scbuf "%S %S\n"
- (fun e d ->
- let t =
- e, d
- in
- if SetTupleString.mem t st then
- st, lst
- else
- SetTupleString.add t st,
- t :: lst)
- with Scanf.Scan_failure _ ->
- failwith
- (Scanf.bscanf scbuf
- "%l"
- (fun line ->
- Printf.sprintf
- "Malformed log file '%s' at line %d"
- default_filename
- line))
- in
- read_aux acc
- end
- else
- begin
- close_in chn;
- List.rev lst
- end
- in
- read_aux (SetTupleString.empty, [])
- end
- else
- begin
- []
- end
-
-
- let register event data =
- let chn_out =
- open_out_gen [Open_append; Open_creat; Open_text] 0o644 default_filename
- in
- Printf.fprintf chn_out "%S %S\n" event data;
- close_out chn_out
-
-
- let unregister event data =
- if Sys.file_exists default_filename then
- begin
- let lst =
- load ()
- in
- let chn_out =
- open_out default_filename
- in
- let write_something =
- ref false
- in
- List.iter
- (fun (e, d) ->
- if e <> event || d <> data then
- begin
- write_something := true;
- Printf.fprintf chn_out "%S %S\n" e d
- end)
- lst;
- close_out chn_out;
- if not !write_something then
- Sys.remove default_filename
- end
-
-
- let filter events =
- let st_events =
- List.fold_left
- (fun st e ->
- SetString.add e st)
- SetString.empty
- events
- in
- List.filter
- (fun (e, _) -> SetString.mem e st_events)
- (load ())
-
-
- let exists event data =
- List.exists
- (fun v -> (event, data) = v)
- (load ())
-end
-
-module BaseBuilt = struct
-(* # 22 "src/base/BaseBuilt.ml" *)
-
-
- open OASISTypes
- open OASISGettext
- open BaseStandardVar
- open BaseMessage
-
-
- type t =
- | BExec (* Executable *)
- | BExecLib (* Library coming with executable *)
- | BLib (* Library *)
- | BObj (* Library *)
- | BDoc (* Document *)
-
-
- let to_log_event_file t nm =
- "built_"^
- (match t with
- | BExec -> "exec"
- | BExecLib -> "exec_lib"
- | BLib -> "lib"
- | BObj -> "obj"
- | BDoc -> "doc")^
- "_"^nm
-
-
- let to_log_event_done t nm =
- "is_"^(to_log_event_file t nm)
-
-
- let register t nm lst =
- BaseLog.register
- (to_log_event_done t nm)
- "true";
- List.iter
- (fun alt ->
- let registered =
- List.fold_left
- (fun registered fn ->
- if OASISFileUtil.file_exists_case fn then
- begin
- BaseLog.register
- (to_log_event_file t nm)
- (if Filename.is_relative fn then
- Filename.concat (Sys.getcwd ()) fn
- else
- fn);
- true
- end
- else
- registered)
- false
- alt
- in
- if not registered then
- warning
- (f_ "Cannot find an existing alternative files among: %s")
- (String.concat (s_ ", ") alt))
- lst
-
-
- let unregister t nm =
- List.iter
- (fun (e, d) ->
- BaseLog.unregister e d)
- (BaseLog.filter
- [to_log_event_file t nm;
- to_log_event_done t nm])
-
-
- let fold t nm f acc =
- List.fold_left
- (fun acc (_, fn) ->
- if OASISFileUtil.file_exists_case fn then
- begin
- f acc fn
- end
- else
- begin
- warning
- (f_ "File '%s' has been marked as built \
- for %s but doesn't exist")
- fn
- (Printf.sprintf
- (match t with
- | BExec | BExecLib ->
- (f_ "executable %s")
- | BLib ->
- (f_ "library %s")
- | BObj ->
- (f_ "object %s")
- | BDoc ->
- (f_ "documentation %s"))
- nm);
- acc
- end)
- acc
- (BaseLog.filter
- [to_log_event_file t nm])
-
-
- let is_built t nm =
- List.fold_left
- (fun is_built (_, d) ->
- (try
- bool_of_string d
- with _ ->
- false))
- false
- (BaseLog.filter
- [to_log_event_done t nm])
-
-
- let of_executable ffn (cs, bs, exec) =
- let unix_exec_is, unix_dll_opt =
- OASISExecutable.unix_exec_is
- (cs, bs, exec)
- (fun () ->
- bool_of_string
- (is_native ()))
- ext_dll
- ext_program
- in
- let evs =
- (BExec, cs.cs_name, [[ffn unix_exec_is]])
- ::
- (match unix_dll_opt with
- | Some fn ->
- [BExecLib, cs.cs_name, [[ffn fn]]]
- | None ->
- [])
- in
- evs,
- unix_exec_is,
- unix_dll_opt
-
-
- let of_library ffn (cs, bs, lib) =
- let unix_lst =
- OASISLibrary.generated_unix_files
- ~ctxt:!BaseContext.default
- ~source_file_exists:(fun fn ->
- OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
- ~is_native:(bool_of_string (is_native ()))
- ~has_native_dynlink:(bool_of_string (native_dynlink ()))
- ~ext_lib:(ext_lib ())
- ~ext_dll:(ext_dll ())
- (cs, bs, lib)
- in
- let evs =
- [BLib,
- cs.cs_name,
- List.map (List.map ffn) unix_lst]
- in
- evs, unix_lst
-
-
- let of_object ffn (cs, bs, obj) =
- let unix_lst =
- OASISObject.generated_unix_files
- ~ctxt:!BaseContext.default
- ~source_file_exists:(fun fn ->
- OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
- ~is_native:(bool_of_string (is_native ()))
- (cs, bs, obj)
- in
- let evs =
- [BObj,
- cs.cs_name,
- List.map (List.map ffn) unix_lst]
- in
- evs, unix_lst
-
-end
-
-module BaseCustom = struct
-(* # 22 "src/base/BaseCustom.ml" *)
-
-
- open BaseEnv
- open BaseMessage
- open OASISTypes
- open OASISGettext
-
-
- let run cmd args extra_args =
- OASISExec.run ~ctxt:!BaseContext.default ~quote:false
- (var_expand cmd)
- (List.map
- var_expand
- (args @ (Array.to_list extra_args)))
-
-
- let hook ?(failsafe=false) cstm f e =
- let optional_command lst =
- let printer =
- function
- | Some (cmd, args) -> String.concat " " (cmd :: args)
- | None -> s_ "No command"
- in
- match
- var_choose
- ~name:(s_ "Pre/Post Command")
- ~printer
- lst with
- | Some (cmd, args) ->
- begin
- try
- run cmd args [||]
- with e when failsafe ->
- warning
- (f_ "Command '%s' fail with error: %s")
- (String.concat " " (cmd :: args))
- (match e with
- | Failure msg -> msg
- | e -> Printexc.to_string e)
- end
- | None ->
- ()
- in
- let res =
- optional_command cstm.pre_command;
- f e
- in
- optional_command cstm.post_command;
- res
-end
-
-module BaseDynVar = struct
-(* # 22 "src/base/BaseDynVar.ml" *)
-
-
- open OASISTypes
- open OASISGettext
- open BaseEnv
- open BaseBuilt
-
-
- let init pkg =
- (* TODO: disambiguate exec vs other variable by adding exec_VARNAME. *)
- (* TODO: provide compile option for library libary_byte_args_VARNAME... *)
- List.iter
- (function
- | Executable (cs, bs, exec) ->
- if var_choose bs.bs_build then
- var_ignore
- (var_redefine
- (* We don't save this variable *)
- ~dump:false
- ~short_desc:(fun () ->
- Printf.sprintf
- (f_ "Filename of executable '%s'")
- cs.cs_name)
- (OASISUtils.varname_of_string cs.cs_name)
- (fun () ->
- let fn_opt =
- fold
- BExec cs.cs_name
- (fun _ fn -> Some fn)
- None
- in
- match fn_opt with
- | Some fn -> fn
- | None ->
- raise
- (PropList.Not_set
- (cs.cs_name,
- Some (Printf.sprintf
- (f_ "Executable '%s' not yet built.")
- cs.cs_name)))))
-
- | Library _ | Object _ | Flag _ | Test _ | SrcRepo _ | Doc _ ->
- ())
- pkg.sections
-end
-
-module BaseTest = struct
-(* # 22 "src/base/BaseTest.ml" *)
-
-
- open BaseEnv
- open BaseMessage
- open OASISTypes
- open OASISExpr
- open OASISGettext
-
-
- let test lst pkg extra_args =
-
- let one_test (failure, n) (test_plugin, cs, test) =
- if var_choose
- ~name:(Printf.sprintf
- (f_ "test %s run")
- cs.cs_name)
- ~printer:string_of_bool
- test.test_run then
- begin
- let () =
- info (f_ "Running test '%s'") cs.cs_name
- in
- let back_cwd =
- match test.test_working_directory with
- | Some dir ->
- let cwd =
- Sys.getcwd ()
- in
- let chdir d =
- info (f_ "Changing directory to '%s'") d;
- Sys.chdir d
- in
- chdir dir;
- fun () -> chdir cwd
-
- | None ->
- fun () -> ()
- in
- try
- let failure_percent =
- BaseCustom.hook
- test.test_custom
- (test_plugin pkg (cs, test))
- extra_args
- in
- back_cwd ();
- (failure_percent +. failure, n + 1)
- with e ->
- begin
- back_cwd ();
- raise e
- end
- end
- else
- begin
- info (f_ "Skipping test '%s'") cs.cs_name;
- (failure, n)
- end
- in
- let failed, n =
- List.fold_left
- one_test
- (0.0, 0)
- lst
- in
- let failure_percent =
- if n = 0 then
- 0.0
- else
- failed /. (float_of_int n)
- in
- let msg =
- Printf.sprintf
- (f_ "Tests had a %.2f%% failure rate")
- (100. *. failure_percent)
- in
- if failure_percent > 0.0 then
- failwith msg
- else
- info "%s" msg;
-
- (* Possible explanation why the tests where not run. *)
- if OASISFeatures.package_test OASISFeatures.flag_tests pkg &&
- not (bool_of_string (BaseStandardVar.tests ())) &&
- lst <> [] then
- BaseMessage.warning
- "Tests are turned off, consider enabling with \
- 'ocaml setup.ml -configure --enable-tests'"
-end
-
-module BaseDoc = struct
-(* # 22 "src/base/BaseDoc.ml" *)
-
-
- open BaseEnv
- open BaseMessage
- open OASISTypes
- open OASISGettext
-
-
- let doc lst pkg extra_args =
-
- let one_doc (doc_plugin, cs, doc) =
- if var_choose
- ~name:(Printf.sprintf
- (f_ "documentation %s build")
- cs.cs_name)
- ~printer:string_of_bool
- doc.doc_build then
- begin
- info (f_ "Building documentation '%s'") cs.cs_name;
- BaseCustom.hook
- doc.doc_custom
- (doc_plugin pkg (cs, doc))
- extra_args
- end
- in
- List.iter one_doc lst;
-
- if OASISFeatures.package_test OASISFeatures.flag_docs pkg &&
- not (bool_of_string (BaseStandardVar.docs ())) &&
- lst <> [] then
- BaseMessage.warning
- "Docs are turned off, consider enabling with \
- 'ocaml setup.ml -configure --enable-docs'"
-end
-
-module BaseSetup = struct
-(* # 22 "src/base/BaseSetup.ml" *)
-
- open BaseEnv
- open BaseMessage
- open OASISTypes
- open OASISSection
- open OASISGettext
- open OASISUtils
-
-
- type std_args_fun =
- package -> string array -> unit
-
-
- type ('a, 'b) section_args_fun =
- name * (package -> (common_section * 'a) -> string array -> 'b)
-
-
- type t =
- {
- configure: std_args_fun;
- build: std_args_fun;
- doc: ((doc, unit) section_args_fun) list;
- test: ((test, float) section_args_fun) list;
- install: std_args_fun;
- uninstall: std_args_fun;
- clean: std_args_fun list;
- clean_doc: (doc, unit) section_args_fun list;
- clean_test: (test, unit) section_args_fun list;
- distclean: std_args_fun list;
- distclean_doc: (doc, unit) section_args_fun list;
- distclean_test: (test, unit) section_args_fun list;
- package: package;
- oasis_fn: string option;
- oasis_version: string;
- oasis_digest: Digest.t option;
- oasis_exec: string option;
- oasis_setup_args: string list;
- setup_update: bool;
- }
-
-
- (* Associate a plugin function with data from package *)
- let join_plugin_sections filter_map lst =
- List.rev
- (List.fold_left
- (fun acc sct ->
- match filter_map sct with
- | Some e ->
- e :: acc
- | None ->
- acc)
- []
- lst)
-
-
- (* Search for plugin data associated with a section name *)
- let lookup_plugin_section plugin action nm lst =
- try
- List.assoc nm lst
- with Not_found ->
- failwithf
- (f_ "Cannot find plugin %s matching section %s for %s action")
- plugin
- nm
- action
-
-
- let configure t args =
- (* Run configure *)
- BaseCustom.hook
- t.package.conf_custom
- (fun () ->
- (* Reload if preconf has changed it *)
- begin
- try
- unload ();
- load ();
- with _ ->
- ()
- end;
-
- (* Run plugin's configure *)
- t.configure t.package args;
-
- (* Dump to allow postconf to change it *)
- dump ())
- ();
-
- (* Reload environment *)
- unload ();
- load ();
-
- (* Save environment *)
- print ();
-
- (* Replace data in file *)
- BaseFileAB.replace t.package.files_ab
-
-
- let build t args =
- BaseCustom.hook
- t.package.build_custom
- (t.build t.package)
- args
-
-
- let doc t args =
- BaseDoc.doc
- (join_plugin_sections
- (function
- | Doc (cs, e) ->
- Some
- (lookup_plugin_section
- "documentation"
- (s_ "build")
- cs.cs_name
- t.doc,
- cs,
- e)
- | _ ->
- None)
- t.package.sections)
- t.package
- args
-
-
- let test t args =
- BaseTest.test
- (join_plugin_sections
- (function
- | Test (cs, e) ->
- Some
- (lookup_plugin_section
- "test"
- (s_ "run")
- cs.cs_name
- t.test,
- cs,
- e)
- | _ ->
- None)
- t.package.sections)
- t.package
- args
-
-
- let all t args =
- let rno_doc =
- ref false
- in
- let rno_test =
- ref false
- in
- let arg_rest =
- ref []
- in
- Arg.parse_argv
- ~current:(ref 0)
- (Array.of_list
- ((Sys.executable_name^" all") ::
- (Array.to_list args)))
- [
- "-no-doc",
- Arg.Set rno_doc,
- s_ "Don't run doc target";
-
- "-no-test",
- Arg.Set rno_test,
- s_ "Don't run test target";
-
- "--",
- Arg.Rest (fun arg -> arg_rest := arg :: !arg_rest),
- s_ "All arguments for configure.";
- ]
- (failwithf (f_ "Don't know what to do with '%s'"))
- "";
-
- info "Running configure step";
- configure t (Array.of_list (List.rev !arg_rest));
-
- info "Running build step";
- build t [||];
-
- (* Load setup.log dynamic variables *)
- BaseDynVar.init t.package;
-
- if not !rno_doc then
- begin
- info "Running doc step";
- doc t [||];
- end
- else
- begin
- info "Skipping doc step"
- end;
-
- if not !rno_test then
- begin
- info "Running test step";
- test t [||]
- end
- else
- begin
- info "Skipping test step"
- end
-
-
- let install t args =
- BaseCustom.hook
- t.package.install_custom
- (t.install t.package)
- args
-
-
- let uninstall t args =
- BaseCustom.hook
- t.package.uninstall_custom
- (t.uninstall t.package)
- args
-
-
- let reinstall t args =
- uninstall t args;
- install t args
-
-
- let clean, distclean =
- let failsafe f a =
- try
- f a
- with e ->
- warning
- (f_ "Action fail with error: %s")
- (match e with
- | Failure msg -> msg
- | e -> Printexc.to_string e)
- in
-
- let generic_clean t cstm mains docs tests args =
- BaseCustom.hook
- ~failsafe:true
- cstm
- (fun () ->
- (* Clean section *)
- List.iter
- (function
- | Test (cs, test) ->
- let f =
- try
- List.assoc cs.cs_name tests
- with Not_found ->
- fun _ _ _ -> ()
- in
- failsafe
- (f t.package (cs, test))
- args
- | Doc (cs, doc) ->
- let f =
- try
- List.assoc cs.cs_name docs
- with Not_found ->
- fun _ _ _ -> ()
- in
- failsafe
- (f t.package (cs, doc))
- args
- | Library _
- | Object _
- | Executable _
- | Flag _
- | SrcRepo _ ->
- ())
- t.package.sections;
- (* Clean whole package *)
- List.iter
- (fun f ->
- failsafe
- (f t.package)
- args)
- mains)
- ()
- in
-
- let clean t args =
- generic_clean
- t
- t.package.clean_custom
- t.clean
- t.clean_doc
- t.clean_test
- args
- in
-
- let distclean t args =
- (* Call clean *)
- clean t args;
-
- (* Call distclean code *)
- generic_clean
- t
- t.package.distclean_custom
- t.distclean
- t.distclean_doc
- t.distclean_test
- args;
-
- (* Remove generated file *)
- List.iter
- (fun fn ->
- if Sys.file_exists fn then
- begin
- info (f_ "Remove '%s'") fn;
- Sys.remove fn
- end)
- (BaseEnv.default_filename
- ::
- BaseLog.default_filename
- ::
- (List.rev_map BaseFileAB.to_filename t.package.files_ab))
- in
-
- clean, distclean
-
-
- let version t _ =
- print_endline t.oasis_version
-
-
- let update_setup_ml, no_update_setup_ml_cli =
- let b = ref true in
- b,
- ("-no-update-setup-ml",
- Arg.Clear b,
- s_ " Don't try to update setup.ml, even if _oasis has changed.")
-
-
- let default_oasis_fn = "_oasis"
-
-
- let update_setup_ml t =
- let oasis_fn =
- match t.oasis_fn with
- | Some fn -> fn
- | None -> default_oasis_fn
- in
- let oasis_exec =
- match t.oasis_exec with
- | Some fn -> fn
- | None -> "oasis"
- in
- let ocaml =
- Sys.executable_name
- in
- let setup_ml, args =
- match Array.to_list Sys.argv with
- | setup_ml :: args ->
- setup_ml, args
- | [] ->
- failwith
- (s_ "Expecting non-empty command line arguments.")
- in
- let ocaml, setup_ml =
- if Sys.executable_name = Sys.argv.(0) then
- (* We are not running in standard mode, probably the script
- * is precompiled.
- *)
- "ocaml", "setup.ml"
- else
- ocaml, setup_ml
- in
- let no_update_setup_ml_cli, _, _ = no_update_setup_ml_cli in
- let do_update () =
- let oasis_exec_version =
- OASISExec.run_read_one_line
- ~ctxt:!BaseContext.default
- ~f_exit_code:
- (function
- | 0 ->
- ()
- | 1 ->
- failwithf
- (f_ "Executable '%s' is probably an old version \
- of oasis (< 0.3.0), please update to version \
- v%s.")
- oasis_exec t.oasis_version
- | 127 ->
- failwithf
- (f_ "Cannot find executable '%s', please install \
- oasis v%s.")
- oasis_exec t.oasis_version
- | n ->
- failwithf
- (f_ "Command '%s version' exited with code %d.")
- oasis_exec n)
- oasis_exec ["version"]
- in
- if OASISVersion.comparator_apply
- (OASISVersion.version_of_string oasis_exec_version)
- (OASISVersion.VGreaterEqual
- (OASISVersion.version_of_string t.oasis_version)) then
- begin
- (* We have a version >= for the executable oasis, proceed with
- * update.
- *)
- (* TODO: delegate this check to 'oasis setup'. *)
- if Sys.os_type = "Win32" then
- failwithf
- (f_ "It is not possible to update the running script \
- setup.ml on Windows. Please update setup.ml by \
- running '%s'.")
- (String.concat " " (oasis_exec :: "setup" :: t.oasis_setup_args))
- else
- begin
- OASISExec.run
- ~ctxt:!BaseContext.default
- ~f_exit_code:
- (function
- | 0 ->
- ()
- | n ->
- failwithf
- (f_ "Unable to update setup.ml using '%s', \
- please fix the problem and retry.")
- oasis_exec)
- oasis_exec ("setup" :: t.oasis_setup_args);
- OASISExec.run ~ctxt:!BaseContext.default ocaml (setup_ml :: args)
- end
- end
- else
- failwithf
- (f_ "The version of '%s' (v%s) doesn't match the version of \
- oasis used to generate the %s file. Please install at \
- least oasis v%s.")
- oasis_exec oasis_exec_version setup_ml t.oasis_version
- in
-
- if !update_setup_ml then
- begin
- try
- match t.oasis_digest with
- | Some dgst ->
- if Sys.file_exists oasis_fn &&
- dgst <> Digest.file default_oasis_fn then
- begin
- do_update ();
- true
- end
- else
- false
- | None ->
- false
- with e ->
- error
- (f_ "Error when updating setup.ml. If you want to avoid this error, \
- you can bypass the update of %s by running '%s %s %s %s'")
- setup_ml ocaml setup_ml no_update_setup_ml_cli
- (String.concat " " args);
- raise e
- end
- else
- false
-
-
- let setup t =
- let catch_exn =
- ref true
- in
- try
- let act_ref =
- ref (fun _ ->
- failwithf
- (f_ "No action defined, run '%s %s -help'")
- Sys.executable_name
- Sys.argv.(0))
-
- in
- let extra_args_ref =
- ref []
- in
- let allow_empty_env_ref =
- ref false
- in
- let arg_handle ?(allow_empty_env=false) act =
- Arg.Tuple
- [
- Arg.Rest (fun str -> extra_args_ref := str :: !extra_args_ref);
-
- Arg.Unit
- (fun () ->
- allow_empty_env_ref := allow_empty_env;
- act_ref := act);
- ]
- in
-
- Arg.parse
- (Arg.align
- ([
- "-configure",
- arg_handle ~allow_empty_env:true configure,
- s_ "[options*] Configure the whole build process.";
-
- "-build",
- arg_handle build,
- s_ "[options*] Build executables and libraries.";
-
- "-doc",
- arg_handle doc,
- s_ "[options*] Build documents.";
-
- "-test",
- arg_handle test,
- s_ "[options*] Run tests.";
-
- "-all",
- arg_handle ~allow_empty_env:true all,
- s_ "[options*] Run configure, build, doc and test targets.";
-
- "-install",
- arg_handle install,
- s_ "[options*] Install libraries, data, executables \
- and documents.";
-
- "-uninstall",
- arg_handle uninstall,
- s_ "[options*] Uninstall libraries, data, executables \
- and documents.";
-
- "-reinstall",
- arg_handle reinstall,
- s_ "[options*] Uninstall and install libraries, data, \
- executables and documents.";
-
- "-clean",
- arg_handle ~allow_empty_env:true clean,
- s_ "[options*] Clean files generated by a build.";
-
- "-distclean",
- arg_handle ~allow_empty_env:true distclean,
- s_ "[options*] Clean files generated by a build and configure.";
-
- "-version",
- arg_handle ~allow_empty_env:true version,
- s_ " Display version of OASIS used to generate this setup.ml.";
-
- "-no-catch-exn",
- Arg.Clear catch_exn,
- s_ " Don't catch exception, useful for debugging.";
- ]
- @
- (if t.setup_update then
- [no_update_setup_ml_cli]
- else
- [])
- @ (BaseContext.args ())))
- (failwithf (f_ "Don't know what to do with '%s'"))
- (s_ "Setup and run build process current package\n");
-
- (* Build initial environment *)
- load ~allow_empty:!allow_empty_env_ref ();
-
- (** Initialize flags *)
- List.iter
- (function
- | Flag (cs, {flag_description = hlp;
- flag_default = choices}) ->
- begin
- let apply ?short_desc () =
- var_ignore
- (var_define
- ~cli:CLIEnable
- ?short_desc
- (OASISUtils.varname_of_string cs.cs_name)
- (fun () ->
- string_of_bool
- (var_choose
- ~name:(Printf.sprintf
- (f_ "default value of flag %s")
- cs.cs_name)
- ~printer:string_of_bool
- choices)))
- in
- match hlp with
- | Some hlp ->
- apply ~short_desc:(fun () -> hlp) ()
- | None ->
- apply ()
- end
- | _ ->
- ())
- t.package.sections;
-
- BaseStandardVar.init t.package;
-
- BaseDynVar.init t.package;
-
- if t.setup_update && update_setup_ml t then
- ()
- else
- !act_ref t (Array.of_list (List.rev !extra_args_ref))
-
- with e when !catch_exn ->
- error "%s" (Printexc.to_string e);
- exit 1
-
-
-end
-
-
-# 5409 "setup.ml"
-module InternalConfigurePlugin = struct
-(* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
-
-
- (** Configure using internal scheme
- @author Sylvain Le Gall
- *)
-
-
- open BaseEnv
- open OASISTypes
- open OASISUtils
- open OASISGettext
- open BaseMessage
-
-
- (** Configure build using provided series of check to be done
- * and then output corresponding file.
- *)
- let configure pkg argv =
- let var_ignore_eval var = let _s: string = var () in () in
- let errors = ref SetString.empty in
- let buff = Buffer.create 13 in
-
- let add_errors fmt =
- Printf.kbprintf
- (fun b ->
- errors := SetString.add (Buffer.contents b) !errors;
- Buffer.clear b)
- buff
- fmt
- in
-
- let warn_exception e =
- warning "%s" (Printexc.to_string e)
- in
-
- (* Check tools *)
- let check_tools lst =
- List.iter
- (function
- | ExternalTool tool ->
- begin
- try
- var_ignore_eval (BaseCheck.prog tool)
- with e ->
- warn_exception e;
- add_errors (f_ "Cannot find external tool '%s'") tool
- end
- | InternalExecutable nm1 ->
- (* Check that matching tool is built *)
- List.iter
- (function
- | Executable ({cs_name = nm2},
- {bs_build = build},
- _) when nm1 = nm2 ->
- if not (var_choose build) then
- add_errors
- (f_ "Cannot find buildable internal executable \
- '%s' when checking build depends")
- nm1
- | _ ->
- ())
- pkg.sections)
- lst
- in
-
- let build_checks sct bs =
- if var_choose bs.bs_build then
- begin
- if bs.bs_compiled_object = Native then
- begin
- try
- var_ignore_eval BaseStandardVar.ocamlopt
- with e ->
- warn_exception e;
- add_errors
- (f_ "Section %s requires native compilation")
- (OASISSection.string_of_section sct)
- end;
-
- (* Check tools *)
- check_tools bs.bs_build_tools;
-
- (* Check depends *)
- List.iter
- (function
- | FindlibPackage (findlib_pkg, version_comparator) ->
- begin
- try
- var_ignore_eval
- (BaseCheck.package ?version_comparator findlib_pkg)
- with e ->
- warn_exception e;
- match version_comparator with
- | None ->
- add_errors
- (f_ "Cannot find findlib package %s")
- findlib_pkg
- | Some ver_cmp ->
- add_errors
- (f_ "Cannot find findlib package %s (%s)")
- findlib_pkg
- (OASISVersion.string_of_comparator ver_cmp)
- end
- | InternalLibrary nm1 ->
- (* Check that matching library is built *)
- List.iter
- (function
- | Library ({cs_name = nm2},
- {bs_build = build},
- _) when nm1 = nm2 ->
- if not (var_choose build) then
- add_errors
- (f_ "Cannot find buildable internal library \
- '%s' when checking build depends")
- nm1
- | _ ->
- ())
- pkg.sections)
- bs.bs_build_depends
- end
- in
-
- (* Parse command line *)
- BaseArgExt.parse argv (BaseEnv.args ());
-
- (* OCaml version *)
- begin
- match pkg.ocaml_version with
- | Some ver_cmp ->
- begin
- try
- var_ignore_eval
- (BaseCheck.version
- "ocaml"
- ver_cmp
- BaseStandardVar.ocaml_version)
- with e ->
- warn_exception e;
- add_errors
- (f_ "OCaml version %s doesn't match version constraint %s")
- (BaseStandardVar.ocaml_version ())
- (OASISVersion.string_of_comparator ver_cmp)
- end
- | None ->
- ()
- end;
-
- (* Findlib version *)
- begin
- match pkg.findlib_version with
- | Some ver_cmp ->
- begin
- try
- var_ignore_eval
- (BaseCheck.version
- "findlib"
- ver_cmp
- BaseStandardVar.findlib_version)
- with e ->
- warn_exception e;
- add_errors
- (f_ "Findlib version %s doesn't match version constraint %s")
- (BaseStandardVar.findlib_version ())
- (OASISVersion.string_of_comparator ver_cmp)
- end
- | None ->
- ()
- end;
- (* Make sure the findlib version is fine for the OCaml compiler. *)
- begin
- let ocaml_ge4 =
- OASISVersion.version_compare
- (OASISVersion.version_of_string (BaseStandardVar.ocaml_version()))
- (OASISVersion.version_of_string "4.0.0") >= 0 in
- if ocaml_ge4 then
- let findlib_lt132 =
- OASISVersion.version_compare
- (OASISVersion.version_of_string (BaseStandardVar.findlib_version()))
- (OASISVersion.version_of_string "1.3.2") < 0 in
- if findlib_lt132 then
- add_errors "OCaml >= 4.0.0 requires Findlib version >= 1.3.2"
- end;
-
- (* FlexDLL *)
- if BaseStandardVar.os_type () = "Win32" ||
- BaseStandardVar.os_type () = "Cygwin" then
- begin
- try
- var_ignore_eval BaseStandardVar.flexlink
- with e ->
- warn_exception e;
- add_errors (f_ "Cannot find 'flexlink'")
- end;
-
- (* Check build depends *)
- List.iter
- (function
- | Executable (_, bs, _)
- | Library (_, bs, _) as sct ->
- build_checks sct bs
- | Doc (_, doc) ->
- if var_choose doc.doc_build then
- check_tools doc.doc_build_tools
- | Test (_, test) ->
- if var_choose test.test_run then
- check_tools test.test_tools
- | _ ->
- ())
- pkg.sections;
-
- (* Check if we need native dynlink (presence of libraries that compile to
- * native)
- *)
- begin
- let has_cmxa =
- List.exists
- (function
- | Library (_, bs, _) ->
- var_choose bs.bs_build &&
- (bs.bs_compiled_object = Native ||
- (bs.bs_compiled_object = Best &&
- bool_of_string (BaseStandardVar.is_native ())))
- | _ ->
- false)
- pkg.sections
- in
- if has_cmxa then
- var_ignore_eval BaseStandardVar.native_dynlink
- end;
-
- (* Check errors *)
- if SetString.empty != !errors then
- begin
- List.iter
- (fun e -> error "%s" e)
- (SetString.elements !errors);
- failwithf
- (fn_
- "%d configuration error"
- "%d configuration errors"
- (SetString.cardinal !errors))
- (SetString.cardinal !errors)
- end
-
-
-end
-
-module InternalInstallPlugin = struct
-(* # 22 "src/plugins/internal/InternalInstallPlugin.ml" *)
-
-
- (** Install using internal scheme
- @author Sylvain Le Gall
- *)
-
-
- open BaseEnv
- open BaseStandardVar
- open BaseMessage
- open OASISTypes
- open OASISFindlib
- open OASISGettext
- open OASISUtils
-
-
- let exec_hook =
- ref (fun (cs, bs, exec) -> cs, bs, exec)
-
-
- let lib_hook =
- ref (fun (cs, bs, lib) -> cs, bs, lib, [])
-
-
- let obj_hook =
- ref (fun (cs, bs, obj) -> cs, bs, obj, [])
-
-
- let doc_hook =
- ref (fun (cs, doc) -> cs, doc)
-
-
- let install_file_ev =
- "install-file"
-
-
- let install_dir_ev =
- "install-dir"
-
-
- let install_findlib_ev =
- "install-findlib"
-
-
- let win32_max_command_line_length = 8000
-
-
- let split_install_command ocamlfind findlib_name meta files =
- if Sys.os_type = "Win32" then
- (* Arguments for the first command: *)
- let first_args = ["install"; findlib_name; meta] in
- (* Arguments for remaining commands: *)
- let other_args = ["install"; findlib_name; "-add"] in
- (* Extract as much files as possible from [files], [len] is
- the current command line length: *)
- let rec get_files len acc files =
- match files with
- | [] ->
- (List.rev acc, [])
- | file :: rest ->
- let len = len + 1 + String.length file in
- if len > win32_max_command_line_length then
- (List.rev acc, files)
- else
- get_files len (file :: acc) rest
- in
- (* Split the command into several commands. *)
- let rec split args files =
- match files with
- | [] ->
- []
- | _ ->
- (* Length of "ocamlfind install [META|-add]" *)
- let len =
- List.fold_left
- (fun len arg ->
- len + 1 (* for the space *) + String.length arg)
- (String.length ocamlfind)
- args
- in
- match get_files len [] files with
- | ([], _) ->
- failwith (s_ "Command line too long.")
- | (firsts, others) ->
- let cmd = args @ firsts in
- (* Use -add for remaining commands: *)
- let () =
- let findlib_ge_132 =
- OASISVersion.comparator_apply
- (OASISVersion.version_of_string
- (BaseStandardVar.findlib_version ()))
- (OASISVersion.VGreaterEqual
- (OASISVersion.version_of_string "1.3.2"))
- in
- if not findlib_ge_132 then
- failwithf
- (f_ "Installing the library %s require to use the \
- flag '-add' of ocamlfind because the command \
- line is too long. This flag is only available \
- for findlib 1.3.2. Please upgrade findlib from \
- %s to 1.3.2")
- findlib_name (BaseStandardVar.findlib_version ())
- in
- let cmds = split other_args others in
- cmd :: cmds
- in
- (* The first command does not use -add: *)
- split first_args files
- else
- ["install" :: findlib_name :: meta :: files]
-
-
- let install pkg argv =
-
- let in_destdir =
- try
- let destdir =
- destdir ()
- in
- (* Practically speaking destdir is prepended
- * at the beginning of the target filename
- *)
- fun fn -> destdir^fn
- with PropList.Not_set _ ->
- fun fn -> fn
- in
-
- let install_file ?tgt_fn src_file envdir =
- let tgt_dir =
- in_destdir (envdir ())
- in
- let tgt_file =
- Filename.concat
- tgt_dir
- (match tgt_fn with
- | Some fn ->
- fn
- | None ->
- Filename.basename src_file)
- in
- (* Create target directory if needed *)
- OASISFileUtil.mkdir_parent
- ~ctxt:!BaseContext.default
- (fun dn ->
- info (f_ "Creating directory '%s'") dn;
- BaseLog.register install_dir_ev dn)
- tgt_dir;
-
- (* Really install files *)
- info (f_ "Copying file '%s' to '%s'") src_file tgt_file;
- OASISFileUtil.cp ~ctxt:!BaseContext.default src_file tgt_file;
- BaseLog.register install_file_ev tgt_file
- in
-
- (* Install data into defined directory *)
- let install_data srcdir lst tgtdir =
- let tgtdir =
- OASISHostPath.of_unix (var_expand tgtdir)
- in
- List.iter
- (fun (src, tgt_opt) ->
- let real_srcs =
- OASISFileUtil.glob
- ~ctxt:!BaseContext.default
- (Filename.concat srcdir src)
- in
- if real_srcs = [] then
- failwithf
- (f_ "Wildcard '%s' doesn't match any files")
- src;
- List.iter
- (fun fn ->
- install_file
- fn
- (fun () ->
- match tgt_opt with
- | Some s ->
- OASISHostPath.of_unix (var_expand s)
- | None ->
- tgtdir))
- real_srcs)
- lst
- in
-
- let make_fnames modul sufx =
- List.fold_right
- begin fun sufx accu ->
- (String.capitalize modul ^ sufx) ::
- (String.uncapitalize modul ^ sufx) ::
- accu
- end
- sufx
- []
- in
-
- (** Install all libraries *)
- let install_libs pkg =
-
- let files_of_library (f_data, acc) data_lib =
- let cs, bs, lib, lib_extra =
- !lib_hook data_lib
- in
- if var_choose bs.bs_install &&
- BaseBuilt.is_built BaseBuilt.BLib cs.cs_name then
- begin
- let acc =
- (* Start with acc + lib_extra *)
- List.rev_append lib_extra acc
- in
- let acc =
- (* Add uncompiled header from the source tree *)
- let path =
- OASISHostPath.of_unix bs.bs_path
- in
- List.fold_left
- begin fun acc modul ->
- begin
- try
- [List.find
- OASISFileUtil.file_exists_case
- (List.map
- (Filename.concat path)
- (make_fnames modul [".mli"; ".ml"]))]
- with Not_found ->
- warning
- (f_ "Cannot find source header for module %s \
- in library %s")
- modul cs.cs_name;
- []
- end
- @
- List.filter
- OASISFileUtil.file_exists_case
- (List.map
- (Filename.concat path)
- (make_fnames modul [".annot";".cmti";".cmt"]))
- @ acc
- end
- acc
- lib.lib_modules
- in
-
- let acc =
- (* Get generated files *)
- BaseBuilt.fold
- BaseBuilt.BLib
- cs.cs_name
- (fun acc fn -> fn :: acc)
- acc
- in
-
- let f_data () =
- (* Install data associated with the library *)
- install_data
- bs.bs_path
- bs.bs_data_files
- (Filename.concat
- (datarootdir ())
- pkg.name);
- f_data ()
- in
-
- (f_data, acc)
- end
- else
- begin
- (f_data, acc)
- end
- and files_of_object (f_data, acc) data_obj =
- let cs, bs, obj, obj_extra =
- !obj_hook data_obj
- in
- if var_choose bs.bs_install &&
- BaseBuilt.is_built BaseBuilt.BObj cs.cs_name then
- begin
- let acc =
- (* Start with acc + obj_extra *)
- List.rev_append obj_extra acc
- in
- let acc =
- (* Add uncompiled header from the source tree *)
- let path =
- OASISHostPath.of_unix bs.bs_path
- in
- List.fold_left
- begin fun acc modul ->
- begin
- try
- [List.find
- OASISFileUtil.file_exists_case
- (List.map
- (Filename.concat path)
- (make_fnames modul [".mli"; ".ml"]))]
- with Not_found ->
- warning
- (f_ "Cannot find source header for module %s \
- in object %s")
- modul cs.cs_name;
- []
- end
- @
- List.filter
- OASISFileUtil.file_exists_case
- (List.map
- (Filename.concat path)
- (make_fnames modul [".annot";".cmti";".cmt"]))
- @ acc
- end
- acc
- obj.obj_modules
- in
-
- let acc =
- (* Get generated files *)
- BaseBuilt.fold
- BaseBuilt.BObj
- cs.cs_name
- (fun acc fn -> fn :: acc)
- acc
- in
-
- let f_data () =
- (* Install data associated with the object *)
- install_data
- bs.bs_path
- bs.bs_data_files
- (Filename.concat
- (datarootdir ())
- pkg.name);
- f_data ()
- in
-
- (f_data, acc)
- end
- else
- begin
- (f_data, acc)
- end
-
- in
-
- (* Install one group of library *)
- let install_group_lib grp =
- (* Iterate through all group nodes *)
- let rec install_group_lib_aux data_and_files grp =
- let data_and_files, children =
- match grp with
- | Container (_, children) ->
- data_and_files, children
- | Package (_, cs, bs, `Library lib, children) ->
- files_of_library data_and_files (cs, bs, lib), children
- | Package (_, cs, bs, `Object obj, children) ->
- files_of_object data_and_files (cs, bs, obj), children
- in
- List.fold_left
- install_group_lib_aux
- data_and_files
- children
- in
-
- (* Findlib name of the root library *)
- let findlib_name =
- findlib_of_group grp
- in
-
- (* Determine root library *)
- let root_lib =
- root_of_group grp
- in
-
- (* All files to install for this library *)
- let f_data, files =
- install_group_lib_aux (ignore, []) grp
- in
-
- (* Really install, if there is something to install *)
- if files = [] then
- begin
- warning
- (f_ "Nothing to install for findlib library '%s'")
- findlib_name
- end
- else
- begin
- let meta =
- (* Search META file *)
- let _, bs, _ =
- root_lib
- in
- let res =
- Filename.concat bs.bs_path "META"
- in
- if not (OASISFileUtil.file_exists_case res) then
- failwithf
- (f_ "Cannot find file '%s' for findlib library %s")
- res
- findlib_name;
- res
- in
- let files =
- (* Make filename shorter to avoid hitting command max line length
- * too early, esp. on Windows.
- *)
- let remove_prefix p n =
- let plen = String.length p in
- let nlen = String.length n in
- if plen <= nlen && String.sub n 0 plen = p then
- begin
- let fn_sep =
- if Sys.os_type = "Win32" then
- '\\'
- else
- '/'
- in
- let cutpoint = plen +
- (if plen < nlen && n.[plen] = fn_sep then
- 1
- else
- 0)
- in
- String.sub n cutpoint (nlen - cutpoint)
- end
- else
- n
- in
- List.map (remove_prefix (Sys.getcwd ())) files
- in
- info
- (f_ "Installing findlib library '%s'")
- findlib_name;
- let ocamlfind = ocamlfind () in
- let commands =
- split_install_command
- ocamlfind
- findlib_name
- meta
- files
- in
- List.iter
- (OASISExec.run ~ctxt:!BaseContext.default ocamlfind)
- commands;
- BaseLog.register install_findlib_ev findlib_name
- end;
-
- (* Install data files *)
- f_data ();
-
- in
-
- let group_libs, _, _ =
- findlib_mapping pkg
- in
-
- (* We install libraries in groups *)
- List.iter install_group_lib group_libs
- in
-
- let install_execs pkg =
- let install_exec data_exec =
- let cs, bs, exec =
- !exec_hook data_exec
- in
- if var_choose bs.bs_install &&
- BaseBuilt.is_built BaseBuilt.BExec cs.cs_name then
- begin
- let exec_libdir () =
- Filename.concat
- (libdir ())
- pkg.name
- in
- BaseBuilt.fold
- BaseBuilt.BExec
- cs.cs_name
- (fun () fn ->
- install_file
- ~tgt_fn:(cs.cs_name ^ ext_program ())
- fn
- bindir)
- ();
- BaseBuilt.fold
- BaseBuilt.BExecLib
- cs.cs_name
- (fun () fn ->
- install_file
- fn
- exec_libdir)
- ();
- install_data
- bs.bs_path
- bs.bs_data_files
- (Filename.concat
- (datarootdir ())
- pkg.name)
- end
- in
- List.iter
- (function
- | Executable (cs, bs, exec)->
- install_exec (cs, bs, exec)
- | _ ->
- ())
- pkg.sections
- in
-
- let install_docs pkg =
- let install_doc data =
- let cs, doc =
- !doc_hook data
- in
- if var_choose doc.doc_install &&
- BaseBuilt.is_built BaseBuilt.BDoc cs.cs_name then
- begin
- let tgt_dir =
- OASISHostPath.of_unix (var_expand doc.doc_install_dir)
- in
- BaseBuilt.fold
- BaseBuilt.BDoc
- cs.cs_name
- (fun () fn ->
- install_file
- fn
- (fun () -> tgt_dir))
- ();
- install_data
- Filename.current_dir_name
- doc.doc_data_files
- doc.doc_install_dir
- end
- in
- List.iter
- (function
- | Doc (cs, doc) ->
- install_doc (cs, doc)
- | _ ->
- ())
- pkg.sections
- in
-
- install_libs pkg;
- install_execs pkg;
- install_docs pkg
-
-
- (* Uninstall already installed data *)
- let uninstall _ argv =
- List.iter
- (fun (ev, data) ->
- if ev = install_file_ev then
- begin
- if OASISFileUtil.file_exists_case data then
- begin
- info
- (f_ "Removing file '%s'")
- data;
- Sys.remove data
- end
- else
- begin
- warning
- (f_ "File '%s' doesn't exist anymore")
- data
- end
- end
- else if ev = install_dir_ev then
- begin
- if Sys.file_exists data && Sys.is_directory data then
- begin
- if Sys.readdir data = [||] then
- begin
- info
- (f_ "Removing directory '%s'")
- data;
- OASISFileUtil.rmdir ~ctxt:!BaseContext.default data
- end
- else
- begin
- warning
- (f_ "Directory '%s' is not empty (%s)")
- data
- (String.concat
- ", "
- (Array.to_list
- (Sys.readdir data)))
- end
- end
- else
- begin
- warning
- (f_ "Directory '%s' doesn't exist anymore")
- data
- end
- end
- else if ev = install_findlib_ev then
- begin
- info (f_ "Removing findlib library '%s'") data;
- OASISExec.run ~ctxt:!BaseContext.default
- (ocamlfind ()) ["remove"; data]
- end
- else
- failwithf (f_ "Unknown log event '%s'") ev;
- BaseLog.unregister ev data)
- (* We process event in reverse order *)
- (List.rev
- (BaseLog.filter
- [install_file_ev;
- install_dir_ev;
- install_findlib_ev]))
-
-
-end
-
-
-# 6273 "setup.ml"
-module OCamlbuildCommon = struct
-(* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
-
-
- (** Functions common to OCamlbuild build and doc plugin
- *)
-
-
- open OASISGettext
- open BaseEnv
- open BaseStandardVar
- open OASISTypes
-
-
-
-
- type extra_args = string list
-
-
- let ocamlbuild_clean_ev = "ocamlbuild-clean"
-
-
- let ocamlbuildflags =
- var_define
- ~short_desc:(fun () -> "OCamlbuild additional flags")
- "ocamlbuildflags"
- (fun () -> "")
-
-
- (** Fix special arguments depending on environment *)
- let fix_args args extra_argv =
- List.flatten
- [
- if (os_type ()) = "Win32" then
- [
- "-classic-display";
- "-no-log";
- "-no-links";
- "-install-lib-dir";
- (Filename.concat (standard_library ()) "ocamlbuild")
- ]
- else
- [];
-
- if not (bool_of_string (is_native ())) || (os_type ()) = "Win32" then
- [
- "-byte-plugin"
- ]
- else
- [];
- args;
-
- if bool_of_string (debug ()) then
- ["-tag"; "debug"]
- else
- [];
-
- if bool_of_string (tests ()) then
- ["-tag"; "tests"]
- else
- [];
-
- if bool_of_string (profile ()) then
- ["-tag"; "profile"]
- else
- [];
-
- OASISString.nsplit (ocamlbuildflags ()) ' ';
-
- Array.to_list extra_argv;
- ]
-
-
- (** Run 'ocamlbuild -clean' if not already done *)
- let run_clean extra_argv =
- let extra_cli =
- String.concat " " (Array.to_list extra_argv)
- in
- (* Run if never called with these args *)
- if not (BaseLog.exists ocamlbuild_clean_ev extra_cli) then
- begin
- OASISExec.run ~ctxt:!BaseContext.default
- (ocamlbuild ()) (fix_args ["-clean"] extra_argv);
- BaseLog.register ocamlbuild_clean_ev extra_cli;
- at_exit
- (fun () ->
- try
- BaseLog.unregister ocamlbuild_clean_ev extra_cli
- with _ ->
- ())
- end
-
-
- (** Run ocamlbuild, unregister all clean events *)
- let run_ocamlbuild args extra_argv =
- (* TODO: enforce that target in args must be UNIX encoded i.e. toto/index.html
- *)
- OASISExec.run ~ctxt:!BaseContext.default
- (ocamlbuild ()) (fix_args args extra_argv);
- (* Remove any clean event, we must run it again *)
- List.iter
- (fun (e, d) -> BaseLog.unregister e d)
- (BaseLog.filter [ocamlbuild_clean_ev])
-
-
- (** Determine real build directory *)
- let build_dir extra_argv =
- let rec search_args dir =
- function
- | "-build-dir" :: dir :: tl ->
- search_args dir tl
- | _ :: tl ->
- search_args dir tl
- | [] ->
- dir
- in
- search_args "_build" (fix_args [] extra_argv)
-
-
-end
-
-module OCamlbuildPlugin = struct
-(* # 22 "src/plugins/ocamlbuild/OCamlbuildPlugin.ml" *)
-
-
- (** Build using ocamlbuild
- @author Sylvain Le Gall
- *)
-
-
- open OASISTypes
- open OASISGettext
- open OASISUtils
- open OASISString
- open BaseEnv
- open OCamlbuildCommon
- open BaseStandardVar
- open BaseMessage
-
-
-
-
-
- let cond_targets_hook =
- ref (fun lst -> lst)
-
-
- let build extra_args pkg argv =
- (* Return the filename in build directory *)
- let in_build_dir fn =
- Filename.concat
- (build_dir argv)
- fn
- in
-
- (* Return the unix filename in host build directory *)
- let in_build_dir_of_unix fn =
- in_build_dir (OASISHostPath.of_unix fn)
- in
-
- let cond_targets =
- List.fold_left
- (fun acc ->
- function
- | Library (cs, bs, lib) when var_choose bs.bs_build ->
- begin
- let evs, unix_files =
- BaseBuilt.of_library
- in_build_dir_of_unix
- (cs, bs, lib)
- in
-
- let tgts =
- List.flatten
- (List.filter
- (fun l -> l <> [])
- (List.map
- (List.filter
- (fun fn ->
- ends_with ~what:".cma" fn
- || ends_with ~what:".cmxs" fn
- || ends_with ~what:".cmxa" fn
- || ends_with ~what:(ext_lib ()) fn
- || ends_with ~what:(ext_dll ()) fn))
- unix_files))
- in
-
- match tgts with
- | _ :: _ ->
- (evs, tgts) :: acc
- | [] ->
- failwithf
- (f_ "No possible ocamlbuild targets for library %s")
- cs.cs_name
- end
-
- | Object (cs, bs, obj) when var_choose bs.bs_build ->
- begin
- let evs, unix_files =
- BaseBuilt.of_object
- in_build_dir_of_unix
- (cs, bs, obj)
- in
-
- let tgts =
- List.flatten
- (List.filter
- (fun l -> l <> [])
- (List.map
- (List.filter
- (fun fn ->
- ends_with ".cmo" fn
- || ends_with ".cmx" fn))
- unix_files))
- in
-
- match tgts with
- | _ :: _ ->
- (evs, tgts) :: acc
- | [] ->
- failwithf
- (f_ "No possible ocamlbuild targets for object %s")
- cs.cs_name
- end
-
- | Executable (cs, bs, exec) when var_choose bs.bs_build ->
- begin
- let evs, unix_exec_is, unix_dll_opt =
- BaseBuilt.of_executable
- in_build_dir_of_unix
- (cs, bs, exec)
- in
-
- let target ext =
- let unix_tgt =
- (OASISUnixPath.concat
- bs.bs_path
- (OASISUnixPath.chop_extension
- exec.exec_main_is))^ext
- in
- let evs =
- (* Fix evs, we want to use the unix_tgt, without copying *)
- List.map
- (function
- | BaseBuilt.BExec, nm, lst when nm = cs.cs_name ->
- BaseBuilt.BExec, nm,
- [[in_build_dir_of_unix unix_tgt]]
- | ev ->
- ev)
- evs
- in
- evs, [unix_tgt]
- in
-
- (* Add executable *)
- let acc =
- match bs.bs_compiled_object with
- | Native ->
- (target ".native") :: acc
- | Best when bool_of_string (is_native ()) ->
- (target ".native") :: acc
- | Byte
- | Best ->
- (target ".byte") :: acc
- in
- acc
- end
-
- | Library _ | Object _ | Executable _ | Test _
- | SrcRepo _ | Flag _ | Doc _ ->
- acc)
- []
- (* Keep the pkg.sections ordered *)
- (List.rev pkg.sections);
- in
-
- (* Check and register built files *)
- let check_and_register (bt, bnm, lst) =
- List.iter
- (fun fns ->
- if not (List.exists OASISFileUtil.file_exists_case fns) then
- failwithf
- (fn_
- "Expected built file %s doesn't exist."
- "None of expected built files %s exists."
- (List.length fns))
- (String.concat (s_ " or ") (List.map (Printf.sprintf "'%s'") fns)))
- lst;
- (BaseBuilt.register bt bnm lst)
- in
-
- (* Run the hook *)
- let cond_targets = !cond_targets_hook cond_targets in
-
- (* Run a list of target... *)
- run_ocamlbuild (List.flatten (List.map snd cond_targets) @ extra_args) argv;
- (* ... and register events *)
- List.iter check_and_register (List.flatten (List.map fst cond_targets))
-
-
- let clean pkg extra_args =
- run_clean extra_args;
- List.iter
- (function
- | Library (cs, _, _) ->
- BaseBuilt.unregister BaseBuilt.BLib cs.cs_name
- | Executable (cs, _, _) ->
- BaseBuilt.unregister BaseBuilt.BExec cs.cs_name;
- BaseBuilt.unregister BaseBuilt.BExecLib cs.cs_name
- | _ ->
- ())
- pkg.sections
-
-
-end
-
-module OCamlbuildDocPlugin = struct
-(* # 22 "src/plugins/ocamlbuild/OCamlbuildDocPlugin.ml" *)
-
-
- (* Create documentation using ocamlbuild .odocl files
- @author Sylvain Le Gall
- *)
-
-
- open OASISTypes
- open OASISGettext
- open OASISMessage
- open OCamlbuildCommon
- open BaseStandardVar
-
-
-
-
- type run_t =
- {
- extra_args: string list;
- run_path: unix_filename;
- }
-
-
- let doc_build run pkg (cs, doc) argv =
- let index_html =
- OASISUnixPath.make
- [
- run.run_path;
- cs.cs_name^".docdir";
- "index.html";
- ]
- in
- let tgt_dir =
- OASISHostPath.make
- [
- build_dir argv;
- OASISHostPath.of_unix run.run_path;
- cs.cs_name^".docdir";
- ]
- in
- run_ocamlbuild (index_html :: run.extra_args) argv;
- List.iter
- (fun glb ->
- BaseBuilt.register
- BaseBuilt.BDoc
- cs.cs_name
- [OASISFileUtil.glob ~ctxt:!BaseContext.default
- (Filename.concat tgt_dir glb)])
- ["*.html"; "*.css"]
-
-
- let doc_clean run pkg (cs, doc) argv =
- run_clean argv;
- BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name
-
-
-end
-
-
-# 6651 "setup.ml"
-module CustomPlugin = struct
-(* # 22 "src/plugins/custom/CustomPlugin.ml" *)
-
-
- (** Generate custom configure/build/doc/test/install system
- @author
- *)
-
-
- open BaseEnv
- open OASISGettext
- open OASISTypes
-
-
-
-
-
- type t =
- {
- cmd_main: command_line conditional;
- cmd_clean: (command_line option) conditional;
- cmd_distclean: (command_line option) conditional;
- }
-
-
- let run = BaseCustom.run
-
-
- let main t _ extra_args =
- let cmd, args =
- var_choose
- ~name:(s_ "main command")
- t.cmd_main
- in
- run cmd args extra_args
-
-
- let clean t pkg extra_args =
- match var_choose t.cmd_clean with
- | Some (cmd, args) ->
- run cmd args extra_args
- | _ ->
- ()
-
-
- let distclean t pkg extra_args =
- match var_choose t.cmd_distclean with
- | Some (cmd, args) ->
- run cmd args extra_args
- | _ ->
- ()
-
-
- module Build =
- struct
- let main t pkg extra_args =
- main t pkg extra_args;
- List.iter
- (fun sct ->
- let evs =
- match sct with
- | Library (cs, bs, lib) when var_choose bs.bs_build ->
- begin
- let evs, _ =
- BaseBuilt.of_library
- OASISHostPath.of_unix
- (cs, bs, lib)
- in
- evs
- end
- | Executable (cs, bs, exec) when var_choose bs.bs_build ->
- begin
- let evs, _, _ =
- BaseBuilt.of_executable
- OASISHostPath.of_unix
- (cs, bs, exec)
- in
- evs
- end
- | _ ->
- []
- in
- List.iter
- (fun (bt, bnm, lst) -> BaseBuilt.register bt bnm lst)
- evs)
- pkg.sections
-
- let clean t pkg extra_args =
- clean t pkg extra_args;
- (* TODO: this seems to be pretty generic (at least wrt to ocamlbuild
- * considering moving this to BaseSetup?
- *)
- List.iter
- (function
- | Library (cs, _, _) ->
- BaseBuilt.unregister BaseBuilt.BLib cs.cs_name
- | Executable (cs, _, _) ->
- BaseBuilt.unregister BaseBuilt.BExec cs.cs_name;
- BaseBuilt.unregister BaseBuilt.BExecLib cs.cs_name
- | _ ->
- ())
- pkg.sections
-
- let distclean t pkg extra_args =
- distclean t pkg extra_args
- end
-
-
- module Test =
- struct
- let main t pkg (cs, test) extra_args =
- try
- main t pkg extra_args;
- 0.0
- with Failure s ->
- BaseMessage.warning
- (f_ "Test '%s' fails: %s")
- cs.cs_name
- s;
- 1.0
-
- let clean t pkg (cs, test) extra_args =
- clean t pkg extra_args
-
- let distclean t pkg (cs, test) extra_args =
- distclean t pkg extra_args
- end
-
-
- module Doc =
- struct
- let main t pkg (cs, _) extra_args =
- main t pkg extra_args;
- BaseBuilt.register BaseBuilt.BDoc cs.cs_name []
-
- let clean t pkg (cs, _) extra_args =
- clean t pkg extra_args;
- BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name
-
- let distclean t pkg (cs, _) extra_args =
- distclean t pkg extra_args
- end
-
-
-end
-
-
-# 6799 "setup.ml"
-open OASISTypes;;
-
-let setup_t =
- {
- BaseSetup.configure = InternalConfigurePlugin.configure;
- build = OCamlbuildPlugin.build [];
- test =
- [
- ("all",
- CustomPlugin.Test.main
- {
- CustomPlugin.cmd_main =
- [(OASISExpr.EBool true, ("make", ["test-all"]))];
- cmd_clean = [(OASISExpr.EBool true, None)];
- cmd_distclean = [(OASISExpr.EBool true, None)]
- })
- ];
- doc =
- [
- ("gen",
- OCamlbuildDocPlugin.doc_build
- {OCamlbuildDocPlugin.extra_args = []; run_path = "."})
- ];
- install = InternalInstallPlugin.install;
- uninstall = InternalInstallPlugin.uninstall;
- clean = [OCamlbuildPlugin.clean];
- clean_test =
- [
- ("all",
- CustomPlugin.Test.clean
- {
- CustomPlugin.cmd_main =
- [(OASISExpr.EBool true, ("make", ["test-all"]))];
- cmd_clean = [(OASISExpr.EBool true, None)];
- cmd_distclean = [(OASISExpr.EBool true, None)]
- })
- ];
- clean_doc =
- [
- ("gen",
- OCamlbuildDocPlugin.doc_clean
- {OCamlbuildDocPlugin.extra_args = []; run_path = "."})
- ];
- distclean = [];
- distclean_test =
- [
- ("all",
- CustomPlugin.Test.distclean
- {
- CustomPlugin.cmd_main =
- [(OASISExpr.EBool true, ("make", ["test-all"]))];
- cmd_clean = [(OASISExpr.EBool true, None)];
- cmd_distclean = [(OASISExpr.EBool true, None)]
- })
- ];
- distclean_doc = [];
- package =
- {
- oasis_version = "0.3";
- ocaml_version = None;
- findlib_version = None;
- alpha_features = [];
- beta_features = [];
- name = "gen";
- version = "0.2.2";
- license =
- OASISLicense.DEP5License
- (OASISLicense.DEP5Unit
- {
- OASISLicense.license = "BSD-3-clause";
- excption = None;
- version = OASISLicense.NoVersion
- });
- license_file = Some "LICENSE";
- copyrights = [];
- maintainers = [];
- authors = ["Simon Cruanes"];
- homepage = Some "https://github.com/c-cube/gen";
- synopsis = "Simple, efficient iterators for OCaml";
- description = None;
- categories = [];
- conf_type = (`Configure, "internal", Some "0.4");
- conf_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- build_type = (`Build, "ocamlbuild", Some "0.4");
- build_custom =
- {
- pre_command =
- [(OASISExpr.EBool true, Some (("make", ["qtest-gen"])))];
- post_command = [(OASISExpr.EBool true, None)]
- };
- install_type = (`Install, "internal", Some "0.4");
- install_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- uninstall_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- clean_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- distclean_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- files_ab = [];
- sections =
- [
- Flag
- ({
- cs_name = "bench";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- flag_description = Some "build benchmark";
- flag_default = [(OASISExpr.EBool true, false)]
- });
- Library
- ({
- cs_name = "gen";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build = [(OASISExpr.EBool true, true)];
- bs_install = [(OASISExpr.EBool true, true)];
- bs_path = ".";
- bs_compiled_object = Best;
- bs_build_depends = [];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {
- lib_modules = ["Gen"; "Gen_intf"];
- lib_pack = false;
- lib_internal_modules = [];
- lib_findlib_parent = None;
- lib_findlib_name = None;
- lib_findlib_containers = []
- });
- Doc
- ({
- cs_name = "gen";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- doc_type = (`Doc, "ocamlbuild", Some "0.3");
- doc_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- doc_build =
- [
- (OASISExpr.ENot (OASISExpr.EFlag "docs"), false);
- (OASISExpr.EFlag "docs", true)
- ];
- doc_install = [(OASISExpr.EBool true, true)];
- doc_install_dir = "$docdir";
- doc_title = "Containers docs";
- doc_authors = [];
- doc_abstract = None;
- doc_format = OtherDoc;
- doc_data_files = [];
- doc_build_tools =
- [ExternalTool "ocamlbuild"; ExternalTool "ocamldoc"]
- });
- Executable
- ({
- cs_name = "run_tests";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EFlag "tests", true)
- ];
- bs_install = [(OASISExpr.EBool true, false)];
- bs_path = "tests/";
- bs_compiled_object = Native;
- bs_build_depends =
- [
- InternalLibrary "gen";
- FindlibPackage ("oUnit", None)
- ];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {exec_custom = false; exec_main_is = "run_tests.ml"});
- Executable
- ({
- cs_name = "run_qtest";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EFlag "tests", true)
- ];
- bs_install = [(OASISExpr.EBool true, false)];
- bs_path = "qtest/";
- bs_compiled_object = Native;
- bs_build_depends =
- [
- FindlibPackage ("containers", None);
- FindlibPackage ("containers.misc", None);
- FindlibPackage ("containers.string", None);
- FindlibPackage ("oUnit", None);
- FindlibPackage ("QTest2Lib", None)
- ];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {exec_custom = false; exec_main_is = "run_qtest.ml"});
- Test
- ({
- cs_name = "all";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- test_type = (`Test, "custom", Some "0.4");
- test_command =
- [(OASISExpr.EBool true, ("make", ["test-all"]))];
- test_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- test_working_directory = None;
- test_run =
- [
- (OASISExpr.ENot (OASISExpr.EFlag "tests"), false);
- (OASISExpr.EFlag "tests", false);
- (OASISExpr.EAnd
- (OASISExpr.EFlag "tests",
- OASISExpr.EFlag "tests"),
- true)
- ];
- test_tools =
- [
- ExternalTool "ocamlbuild";
- InternalExecutable "run_tests";
- InternalExecutable "run_qtest"
- ]
- });
- Executable
- ({
- cs_name = "bench_persistent";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EFlag "bench", true)
- ];
- bs_install = [(OASISExpr.EBool true, false)];
- bs_path = "bench/";
- bs_compiled_object = Native;
- bs_build_depends =
- [
- InternalLibrary "gen";
- FindlibPackage ("benchmark", None)
- ];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {exec_custom = false; exec_main_is = "bench_persistent.ml"
- });
- SrcRepo
- ({
- cs_name = "head";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- src_repo_type = Git;
- src_repo_location = "https://github.com/c-cube/gen";
- src_repo_browser =
- Some "https://github.com/c-cube/gen/tree/master/src";
- src_repo_module = None;
- src_repo_branch = None;
- src_repo_tag = None;
- src_repo_subdir = None
- })
- ];
- plugins =
- [(`Extra, "META", Some "0.3"); (`Extra, "DevFiles", Some "0.3")];
- disable_oasis_section = [];
- schema_data = PropList.Data.create ();
- plugin_data = []
- };
- oasis_fn = Some "_oasis";
- oasis_version = "0.4.5";
- oasis_digest = Some "&R\193\241\164\161\179\006\021\1643N\0163\245K";
- oasis_exec = None;
- oasis_setup_args = [];
- setup_update = false
- };;
-
-let setup () = BaseSetup.setup setup_t;;
-
-# 7149 "setup.ml"
-(* OASIS_STOP *)
-let () = setup ();;
diff --git a/gen/tests/run_tests.ml b/gen/tests/run_tests.ml
deleted file mode 100644
index 19afd2ed..00000000
--- a/gen/tests/run_tests.ml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-let () =
- let _ = OUnit.run_test_tt_main Test_gen.suite in
- ()
diff --git a/gen/tests/test_gen.ml b/gen/tests/test_gen.ml
deleted file mode 100644
index fc968ab1..00000000
--- a/gen/tests/test_gen.ml
+++ /dev/null
@@ -1,146 +0,0 @@
-
-open OUnit
-open Gen.Infix
-
-module GR = Gen.Restart
-
-let pint i = string_of_int i
-let pilist l =
- let b = Buffer.create 15 in
- let fmt = Format.formatter_of_buffer b in
- Format.fprintf fmt "%a@?"
- (Gen.pp Format.pp_print_int) (Gen.of_list l);
- Buffer.contents b
-let pi2list l =
- let b = Buffer.create 15 in
- let fmt = Format.formatter_of_buffer b in
- Format.fprintf fmt "%a@?"
- (Gen.pp (fun fmt (a,b) -> Format.fprintf fmt "%d,%d" a b))
- (Gen.of_list l);
- Buffer.contents b
-let pstrlist l =
- let b = Buffer.create 15 in
- let fmt = Format.formatter_of_buffer b in
- Format.fprintf fmt "%a@?"
- (Gen.pp Format.pp_print_string) (Gen.of_list l);
- Buffer.contents b
-
-let test_singleton () =
- let gen = Gen.singleton 42 in
- OUnit.assert_equal (Some 42) (Gen.get gen);
- OUnit.assert_equal None (Gen.get gen);
- let gen = Gen.singleton 42 in
- OUnit.assert_equal 1 (Gen.length gen);
- ()
-
-let test_iter () =
- let e = GR.(1 -- 10) in
- OUnit.assert_equal ~printer:pint 10 (GR.length e);
- OUnit.assert_equal [1;2] GR.(to_list (1 -- 2));
- OUnit.assert_equal [1;2;3;4;5] (GR.to_list (GR.take 5 e));
- ()
-
-let test_map () =
- let e = 1 -- 10 in
- let e' = Gen.map string_of_int e in
- OUnit.assert_equal ~printer:pstrlist ["9"; "10"] (Gen.to_list (Gen.drop 8 e'));
- ()
-
-let test_append () =
- let e = Gen.append (1 -- 5) (6 -- 10) in
- OUnit.assert_equal [10;9;8;7;6;5;4;3;2;1] (Gen.to_rev_list e);
- ()
-
-let test_flat_map () =
- let e = 1 -- 3 in
- let e' = e >>= (fun x -> x -- (x+1)) in
- OUnit.assert_equal [1;2;2;3;3;4] (Gen.to_list e');
- ()
-
-let test_zip () =
- let e = Gen.zip_with (+) (Gen.repeat 1) (4--7) in
- OUnit.assert_equal [5;6;7;8] (Gen.to_list e);
- ()
-
-let test_filter_map () =
- let f x = if x mod 2 = 0 then Some (string_of_int x) else None in
- let e = Gen.filter_map f (1 -- 10) in
- OUnit.assert_equal ["2"; "4"; "6"; "8"; "10"] (Gen.to_list e);
- ()
-
-let test_merge () =
- let e = Gen.of_list [1--3; 4--6; 7--9] in
- let e' = Gen.merge e in
- OUnit.assert_equal [1;2;3;4;5;6;7;8;9] (Gen.to_list e' |> List.sort compare);
- ()
-
-let test_persistent () =
- let i = ref 0 in
- let gen () =
- let j = !i in
- if j > 5 then None else (incr i; Some j)
- in
- let e = Gen.persistent gen in
- OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
- OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
- OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
- ()
-
-let test_round_robin () =
- let e = GR.round_robin ~n:2 GR.(1--10) in
- match e with
- | [a;b] ->
- OUnit.assert_equal [1;3;5;7;9] (Gen.to_list a);
- OUnit.assert_equal [2;4;6;8;10] (Gen.to_list b)
- | _ -> OUnit.assert_failure "wrong list lenght"
-
-let test_big_rr () =
- let e = GR.round_robin ~n:3 GR.(1 -- 999) in
- let l = List.map Gen.length e in
- OUnit.assert_equal [333;333;333] l;
- ()
-
-let test_merge_sorted () =
- [Gen.of_list [1;3;5]; Gen.of_list [0;1;1;3;4;6;10]; Gen.of_list [2;2;11]]
- |> Gen.sorted_merge_n ?cmp:None
- |> Gen.to_list
- |> OUnit.assert_equal ~printer:pilist [0;1;1;1;2;2;3;3;4;5;6;10;11]
-
-let test_interleave () =
- let e1 = Gen.of_list [1;3;5;7;9] in
- let e2 = Gen.of_list [2;4;6;8;10] in
- let e = Gen.interleave e1 e2 in
- OUnit.assert_equal [1;2;3;4;5;6;7;8;9;10] (Gen.to_list e);
- ()
-
-let test_intersperse () =
- let e = 1 -- 5 in
- let e' = Gen.intersperse 0 e in
- OUnit.assert_equal [1;0;2;0;3;0;4;0;5] (Gen.to_list e');
- ()
-
-let test_product () =
- let printer = pi2list in
- let e = Gen.product (1--3) (4--5) in
- OUnit.assert_equal ~printer [1,4; 1,5; 2,4; 2,5; 3,4; 3,5]
- (List.sort compare (Gen.to_list e));
- ()
-
-let suite =
- "test_gen" >:::
- [ "test_singleton" >:: test_singleton;
- "test_iter" >:: test_iter;
- "test_map" >:: test_map;
- "test_append" >:: test_append;
- "test_flat_map" >:: test_flat_map;
- "test_zip" >:: test_zip;
- "test_filter_map" >:: test_filter_map;
- "test_merge" >:: test_merge;
- "test_persistent" >:: test_persistent;
- "test_round_robin" >:: test_round_robin;
- "test_big_rr" >:: test_big_rr;
- "test_merge_sorted" >:: test_merge_sorted;
- "test_interleave" >:: test_interleave;
- "test_intersperse" >:: test_intersperse;
- "test_product" >:: test_product;
- ]
diff --git a/lwt/behavior.ml b/lwt/behavior.ml
deleted file mode 100644
index dbf1e168..00000000
--- a/lwt/behavior.ml
+++ /dev/null
@@ -1,164 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Behavior Trees for React} *)
-
-(** {2 Behavior tree} *)
-
-type tree =
- | Test of (unit -> bool) (* call and test value *)
- | Wait of (unit -> bool Lwt.t) (* wait for the future to complete *)
- | Do of (unit -> bool) (* perform an action *)
- | If of (unit -> bool) * tree * tree (* switch *)
- | Sequence of bool * tree list (* yield to subtrees sequentially. bool: loop? *)
- | Select of select_strategy * tree list (* select one subtree *)
- | Parallel of parallel_strategy * tree list (* run all subtrees in parallel *)
- | Closure of (unit -> tree) (* build a tree dynamically *)
- | Succeed (* always succeed *)
- | Fail (* always fail *)
- (** A behavior tree *)
-and select_strategy = tree list -> (unit -> tree option)
- (** How to select a subtree to run. It yields a subtree until it
- decides to fail *)
-and parallel_strategy =
- | PSForall (** succeeds when all subtrees succeed *)
- | PSExists (** succeeds when some subtree succeeds *)
-
-let strategy_inorder l =
- let cur = ref l in
- fun () -> match !cur with
- | [] -> None
- | t::l' ->
- cur := l';
- Some t
-
-let strategy_random ?(proba_fail=0.05) l =
- let a = Array.of_list l in
- fun () ->
- if Random.float 1. < proba_fail
- then None
- else (* choose in array *)
- let t = a.(Random.int (Array.length a)) in
- Some t
-
-let succeed = Succeed
-
-let fail = Fail
-
-let test f = Test f
-
-let wait fut = Wait (fun () -> fut)
-
-let wait_ fut = Wait (fun () -> Lwt.bind fut (fun () -> Lwt.return_true))
-
-let wait_closure f = Wait f
-
-let timeout f = Wait (fun () -> Lwt.bind (Lwt_unix.sleep f) (fun () -> Lwt.return_false))
-
-let delay f = Wait (fun () -> Lwt.bind (Lwt_unix.sleep f) (fun () -> Lwt.return_true))
-
-let do_ act = Do act
-
-let do_succeed act = Do (fun () -> act (); true)
-
-let if_ s then_ else_ = If (s, then_, else_)
-
-let when_ s t = if_ s t succeed
-
-let while_ f l = Sequence (true, (test f) :: l)
-
-let sequence ?(loop=false) l =
- assert (l <> []);
- Sequence (loop, l)
-
-let repeat t = sequence ~loop:true [t]
-
-let select ?(strat=strategy_inorder) l =
- assert (l <> []);
- Select (strat, l)
-
-let or_else t1 t2 =
- select ~strat:strategy_inorder [t1; t2]
-
-let parallel ?(strat=PSForall) l =
- assert (l <> []);
- Parallel (strat, l)
-
-let closure f =
- Closure f
-
-(** {2 Run a tree} *)
-
-type result = bool Lwt.t
-
-let run tree =
- let (>>=) = Lwt.(>>=) in
- (* run given tree *)
- let rec run tree =
- match tree with
- | Test f -> Lwt.return (f ())
- | Wait f -> f ()
- | Do act -> if act () then Lwt.return_true else Lwt.return_false
- | If (s, then_, else_) -> (* depends on value returned by [s] *)
- if s () then run then_ else run else_
- | Sequence (loop, l) -> run_sequence ~loop l
- | Select (strat, l) -> run_select ~strat l
- | Parallel (strat, l) -> run_parallel ~strat l
- | Closure f -> let tree' = f () in run tree'
- | Succeed -> Lwt.return_true
- | Fail -> Lwt.return_false
- and run_sequence ~loop start =
- let rec process l = match l with
- | [] when loop -> run_sequence ~loop start
- | [] -> Lwt.return_true (* success *)
- | t::l' ->
- let res_t = run t in
- res_t >>= fun t_succeeded ->
- if t_succeeded
- then process l'
- else Lwt.return_false
- in
- process start
- and run_select ~strat l =
- (* choice function *)
- let choose = strat l in
- (* try a subtree *)
- let rec try_one () =
- match choose () with
- | None -> Lwt.return_false (* failure *)
- | Some t ->
- run t >>= fun t_succeeded ->
- if t_succeeded
- then Lwt.return_true
- else try_one ()
- in
- try_one ()
- and run_parallel ~strat l =
- let results = List.map run l in
- match strat with
- | PSExists -> Lwt_list.exists_p (fun x -> x) results
- | PSForall -> Lwt_list.for_all_p (fun x -> x) results
- in
- run tree
diff --git a/lwt/behavior.mli b/lwt/behavior.mli
deleted file mode 100644
index 18903df5..00000000
--- a/lwt/behavior.mli
+++ /dev/null
@@ -1,142 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Behavior Trees for Lwt} *)
-
-(** Behavior trees are a modular alternative to state machines for controlling
- dynamic behavior in time. They are primarily used in video games to
- implement non-player AI.
-
- A tree is composed of basic actions, basic tests, and combinators. During
- execution, some subset of the nodes of a tree may be {b running}; at some
- point the execution of a given node will terminate with either
- {b success} or {b failure}. Depending on the kind of node, this result
- may propagate to parent nodes, or set other nodes running.
-
- For instance, a {i sequence} node runs its subtrees one by one. If a
- subtree succeeds, the next one is activated; if it fails, the whole
- sequence will fail.
-
- Here, we build them on top of
- {{: http://ocsigen.org/lwt/} Lwt}.
-
- Documentation source:
- {{: http://aigamedev.com/open/article/bt-overview/} aigamedev (and links)}
-*)
-
-(** {2 Behavior tree} *)
-
-(** A behavior tree *)
-type tree = private
- | Test of (unit -> bool) (* call and test value *)
- | Wait of (unit -> bool Lwt.t) (* wait for the future to complete *)
- | Do of (unit -> bool) (* perform an action *)
- | If of (unit -> bool) * tree * tree (* switch *)
- | Sequence of bool * tree list (* yield to subtrees sequentially. bool: loop? *)
- | Select of select_strategy * tree list (* select one subtree *)
- | Parallel of parallel_strategy * tree list (* run all subtrees in parallel *)
- | Closure of (unit -> tree) (* build a tree dynamically *)
- | Succeed (* always succeed *)
- | Fail (* always fail *)
-
-and select_strategy = tree list -> (unit -> tree option)
- (** How to select a subtree to run. It may yield a different result each
- time it is called. *)
-
-and parallel_strategy =
- | PSForall (** succeeds when all subtrees succeed *)
- | PSExists (** succeeds when some subtree succeeds (kill the others) *)
-
-val strategy_inorder : select_strategy
- (** Select subnodes one after the other, then fails *)
-
-val strategy_random : ?proba_fail:float -> select_strategy
- (** Randomly chooses a subtree. May fail at each point with
- a probability of [proba_fail]. *)
-
-val succeed : tree
- (** Behavior that always succeeds *)
-
-val fail : tree
- (** Behavior that always fails *)
-
-val test : (unit -> bool) -> tree
- (** Fails or succeeds based on the next occurrence of the event *)
-
-val wait : bool Lwt.t -> tree
- (** Returns the same result as the future *)
-
-val wait_ : unit Lwt.t -> tree
- (** Wait for the future to complete, then succeed *)
-
-val wait_closure : (unit -> bool Lwt.t) -> tree
-
-val timeout : float -> tree
- (** Fails after the given amount of seconds *)
-
-val delay : float -> tree
- (** Wait for the given amount of seconds, then succeed *)
-
-val do_ : (unit -> bool) -> tree
- (** Perform an action, then succeed iff it returned true *)
-
-val do_succeed : (unit -> unit) -> tree
- (** Perform an action and succeed (unless it raises an exception) *)
-
-val if_ : (unit -> bool) -> tree -> tree -> tree
- (** Conditional choice, based on the current value of the signal *)
-
-val when_ : (unit -> bool) -> tree -> tree
- (** Run the given tree if the signal is true, else succeed *)
-
-val while_ : (unit -> bool) -> tree list -> tree
- (** While the signal is true, run the subtrees *)
-
-val sequence : ?loop:bool -> tree list -> tree
- (** Sequence of sub-trees to run *)
-
-val repeat : tree -> tree
- (** Repeat the same tree indefinitely *)
-
-val select : ?strat:select_strategy -> tree list -> tree
- (** Choice among the subtrees. The strategy defines in which order subtrees
- are tried. *)
-
-val or_else : tree -> tree -> tree
- (** Binary choice, favoring the left one *)
-
-val parallel : ?strat:parallel_strategy -> tree list -> tree
- (** Run subtrees in parallel (default strat: PSForall) *)
-
-val closure : (unit -> tree) -> tree
- (** Produce a tree dynamically, at each call. *)
-
-(** {2 Run a tree} *)
-
-type result = bool Lwt.t
-
-val run : tree -> result
- (** Run the tree. It returns a {! result}, which wraps
- either true (success) or false (failure). *)
diff --git a/media/logo.png b/media/logo.png
new file mode 100644
index 00000000..df7b3d7f
Binary files /dev/null and b/media/logo.png differ
diff --git a/myocamlbuild.ml b/myocamlbuild.ml
index f5059687..1ac57545 100644
--- a/myocamlbuild.ml
+++ b/myocamlbuild.ml
@@ -1,5 +1,5 @@
(* OASIS_START *)
-(* DO NOT EDIT (digest: 533979157febab9fa15b0b406be9633e) *)
+(* DO NOT EDIT (digest: e3363561f51c33bc1d07d0c9f2bd631a) *)
module OASISGettext = struct
(* # 22 "src/oasis/OASISGettext.ml" *)
@@ -609,31 +609,52 @@ let package_default =
{
MyOCamlbuildBase.lib_ocaml =
[
- ("containers", ["core"], []);
- ("containers_string", ["string"], []);
- ("containers_advanced", ["advanced"], []);
- ("containers_pervasives", ["pervasives"], []);
- ("containers_misc", ["misc"], []);
- ("containers_thread", ["threads"], []);
- ("containers_lwt", ["lwt"], []);
- ("containers_cgi", ["cgi"], [])
+ ("containers", ["src/core"], []);
+ ("containers_io", ["src/io"], []);
+ ("containers_sexp", ["src/sexp"], []);
+ ("containers_data", ["src/data"], []);
+ ("containers_iter", ["src/iter"], []);
+ ("containers_string", ["src/string"], []);
+ ("containers_advanced", ["src/advanced"], []);
+ ("containers_bigarray", ["src/bigarray"], []);
+ ("containers_pervasives", ["src/pervasives"], []);
+ ("containers_misc", ["src/misc"], []);
+ ("containers_thread", ["src/threads"], []);
+ ("containers_lwt", ["src/lwt"], [])
];
lib_c = [];
flags = [];
includes =
[
- ("threads", ["core"]);
- ("tests/lwt", ["core"; "lwt"]);
- ("tests", ["core"; "misc"; "string"]);
- ("qtest", ["core"; "misc"; "string"]);
- ("pervasives", ["core"]);
- ("misc", ["core"]);
- ("lwt", ["core"; "misc"]);
- ("examples/cgi", ["cgi"; "core"]);
- ("examples", ["core"; "misc"]);
- ("cgi", ["core"]);
- ("benchs", ["advanced"; "core"; "misc"; "string"]);
- ("advanced", ["core"])
+ ("tests/lwt", ["src/core"; "src/lwt"]);
+ ("tests", ["src/core"; "src/data"; "src/misc"; "src/string"]);
+ ("src/threads", ["src/core"]);
+ ("src/pervasives", ["src/core"]);
+ ("src/misc", ["src/core"; "src/data"]);
+ ("src/lwt", ["src/core"; "src/misc"]);
+ ("src/bigarray", ["src/core"]);
+ ("src/advanced", ["src/core"]);
+ ("qtest",
+ [
+ "src/advanced";
+ "src/bigarray";
+ "src/core";
+ "src/io";
+ "src/iter";
+ "src/misc";
+ "src/sexp";
+ "src/string"
+ ]);
+ ("examples", ["src/core"; "src/misc"; "src/sexp"]);
+ ("benchs",
+ [
+ "src/advanced";
+ "src/core";
+ "src/data";
+ "src/iter";
+ "src/misc";
+ "src/string"
+ ])
]
}
;;
@@ -642,8 +663,11 @@ let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
-# 646 "myocamlbuild.ml"
+# 667 "myocamlbuild.ml"
(* OASIS_STOP *)
+
+let doc_intro = "doc/intro.txt" ;;
+
Ocamlbuild_plugin.dispatch dispatch_default;;
dispatch
@@ -652,17 +676,17 @@ dispatch
| After_rules ->
(* replace with Ocamlbuild_cppo.dispatch when 4.00 is not supported
anymore *)
- let dep = "%(name).cppo.ml" in
+ let dep_cppo = "%(name).cppo.ml" in
let prod1 = "%(name: <*> and not <*.cppo>).ml" in
let prod2 = "%(name: <**/*> and not <**/*.cppo>).ml" in
let f prod env _build =
- let dep = env dep in
+ let dep = env dep_cppo in
let prod = env prod in
let tags = tags_of_pathname prod ++ "cppo" in
Cmd (S[A "cppo"; T tags; S [A "-o"; P prod]; P dep ])
in
- rule "cppo1" ~dep ~prod:prod1 (f prod1) ;
- rule "cppo2" ~dep ~prod:prod2 (f prod2) ;
+ rule "cppo1" ~dep:dep_cppo ~prod:prod1 (f prod1) ;
+ rule "cppo2" ~dep:dep_cppo ~prod:prod2 (f prod2) ;
pflag ["cppo"] "cppo_D" (fun s -> S [A "-D"; A s]) ;
pflag ["cppo"] "cppo_U" (fun s -> S [A "-U"; A s]) ;
pflag ["cppo"] "cppo_I" (fun s ->
@@ -683,7 +707,15 @@ dispatch
let ocaml_major = "OCAML_MAJOR " ^ string_of_int major in
let ocaml_minor = "OCAML_MINOR " ^ string_of_int minor in
- flag ["cppo"] & S[A"-D"; A ocaml_major; A"-D"; A ocaml_minor]
+ flag ["cppo"] & S[A"-D"; A ocaml_major; A"-D"; A ocaml_minor] ;
+
+ (* Documentation index *)
+ dep ["ocaml"; "doc"; "extension:html"] & [doc_intro] ;
+ flag ["ocaml"; "doc"; "extension:html"] &
+ (S[A"-t"; A"Containers doc";
+ A"-intro"; P doc_intro;
+ ]);
+
| _ -> ()
end;
dispatch_default
diff --git a/opam b/opam
index 2e55f8ea..e20b12c0 100644
--- a/opam
+++ b/opam
@@ -3,7 +3,8 @@ author: "Simon Cruanes"
maintainer: "simon.cruanes@inria.fr"
build: [
["./configure" "--prefix" prefix "--disable-thread" "--disable-bench"
- "--disable-tests" "--disable-cgi" "--%{lwt:enable}%-lwt"
+ "--disable-tests" "--%{lwt:enable}%-lwt"
+ "--%{base-bigarray:enable}%-bigarray"
"--enable-docs" "--enable-misc"]
[make "build"]
]
@@ -16,7 +17,10 @@ remove: [
["ocamlfind" "remove" "containers"]
]
post-messages: [
- "in containers, modules start with 'CC' (stands for 'core containers')"
+ "containers is now split into finer-grained sub-libraries, including
+ `containers.io`, `containers.iter`, `containers.sexp`, `containers.data`.
+ CCGen and CCSequence have been removed, consider using the libraries
+ `gen` and `sequence` on opam."
]
depends: [
"ocamlfind" {build}
diff --git a/sequence/.gitignore b/sequence/.gitignore
deleted file mode 100644
index 96cadb3a..00000000
--- a/sequence/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.*.swp
-_build
-*.native
-*.docdir
-*.html
-man/
-sequence.install
-setup.log
-setup.data
diff --git a/sequence/.merlin b/sequence/.merlin
deleted file mode 100644
index d9043276..00000000
--- a/sequence/.merlin
+++ /dev/null
@@ -1,9 +0,0 @@
-S .
-S bench/
-S tests/
-B _build
-B _build/tests/
-B _build/bench/
-PKG oUnit
-PKG benchmark
-FLAG -safe-string
diff --git a/sequence/.ocamlinit b/sequence/.ocamlinit
deleted file mode 100644
index 7123b8dc..00000000
--- a/sequence/.ocamlinit
+++ /dev/null
@@ -1,9 +0,0 @@
-#directory "_build";;
-#load "sequence.cma";;
-
-open Sequence.Infix;;
-
-#directory "_build/bigarray/";;
-#load "bigarray.cma";;
-
-(* vim:syntax=ocaml *)
diff --git a/sequence/CHANGELOG.md b/sequence/CHANGELOG.md
deleted file mode 100644
index 08c0e5a1..00000000
--- a/sequence/CHANGELOG.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# Changelog
-
-## 0.5
-
-- conversion with `klist`
-- add monadic, choice and applicative infix operators and `>|=`
-- add several functions:
- * `product2`
- * `find`, `mem`
- * `doubleton`, `cons`, `snoc`
- * `drop_while`, `take_while`...
- * `concat_str`
-- aliases to existing functions
-- use `delimcc` in a new module, `SequenceInvert`, in order to reverse the
- control flow (here with conversion to Gen)
-- fix examples, tests and doc (about `product`)
-- reading benchmark for persistent sequences.
-- replace `Bench` with `Benchmark`
-
-## 0.4.1
-
-- `persistent_lazy`
-- use bin_annot
-
-## 0.4
-
-- API change for `persistent`
-- more efficient implementation for `persistent`
-- remove `TypeClass`
-- API change for `min`/`max` (in case the sequence is empty)
-- conversion with `Gen`
-- use Oasis
-
-## 0.3.7
-
-- decreasing int range
-- printing functions
-
-## 0.3.6.1
-
-- documentation
-- bugfixes
-
-## 0.3.6
-
-- `fmap`
-- functors to adapt `Set` and `Map`
-
-## 0.3.5
-
-- tests and benchmarks
-- `join` combinator
-- optimization for `Sequence.persistent`
-
-## 0.3.4
-
-- `sort`, `uniq`, `group` and `sort_uniq` combinators implemented
-- some conversion functions that use `Sequence.t2`
-- infix operators in `Sequence.Infix`
-- `Sequence.t2` type for efficient iteration on pairs of elements
-- some combinators are adapted to `Sequence.t2`
-- `zip`, `unzip` and `zip_i` to convert between `t` and `t2`
-- added `scan` combinator
-
-note: git log --no-merges previous_version..HEAD --pretty=%s
diff --git a/sequence/LICENSE b/sequence/LICENSE
deleted file mode 100644
index 7e29992c..00000000
--- a/sequence/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2012, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and
-the following disclaimer in the documentation and/or other materials
-provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/sequence/META b/sequence/META
deleted file mode 100644
index e2f9a7da..00000000
--- a/sequence/META
+++ /dev/null
@@ -1,11 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: 1e28d93f3671e8db9acf63b73cdbca82)
-version = "0.4.1"
-description = "Simple sequence (iterator) datatype and combinators"
-archive(byte) = "sequence.cma"
-archive(byte, plugin) = "sequence.cma"
-archive(native) = "sequence.cmxa"
-archive(native, plugin) = "sequence.cmxs"
-exists_if = "sequence.cma"
-# OASIS_STOP
-
diff --git a/sequence/Makefile b/sequence/Makefile
deleted file mode 100644
index db135eec..00000000
--- a/sequence/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: a3c674b4239234cbbe53afe090018954)
-
-SETUP = ocaml setup.ml
-
-build: setup.data
- $(SETUP) -build $(BUILDFLAGS)
-
-doc: setup.data build
- $(SETUP) -doc $(DOCFLAGS)
-
-test: setup.data build
- $(SETUP) -test $(TESTFLAGS)
-
-all:
- $(SETUP) -all $(ALLFLAGS)
-
-install: setup.data
- $(SETUP) -install $(INSTALLFLAGS)
-
-uninstall: setup.data
- $(SETUP) -uninstall $(UNINSTALLFLAGS)
-
-reinstall: setup.data
- $(SETUP) -reinstall $(REINSTALLFLAGS)
-
-clean:
- $(SETUP) -clean $(CLEANFLAGS)
-
-distclean:
- $(SETUP) -distclean $(DISTCLEANFLAGS)
-
-setup.data:
- $(SETUP) -configure $(CONFIGUREFLAGS)
-
-configure:
- $(SETUP) -configure $(CONFIGUREFLAGS)
-
-.PHONY: build doc test all install uninstall reinstall clean distclean configure
-
-# OASIS_STOP
-
-run-tests:
- ./run_tests.native
-
-examples:
- ocamlbuild examples/test_sexpr.native
-
-push_doc: all doc
- scp -r sequence.docdir/* cedeela.fr:~/simon/root/software/sequence/
-
-push_stable: all
- git checkout stable
- git merge master -m 'merge from master'
- oasis setup
- git commit -a -m 'oasis files'
- git push origin
- git checkout master
-
-VERSION=$(shell awk '^/Version:/ {print $$2}' _oasis)
-
-update_next_tag:
- @echo "update version to $(VERSION)..."
- sed -i "s/NEXT_VERSION/$(VERSION)/g" *.ml *.mli
- sed -i "s/NEXT_RELEASE/$(VERSION)/g" *.ml *.mli
-
-.PHONY: benchs tests examples update_next_tag push_doc push_stable
diff --git a/sequence/README.md b/sequence/README.md
deleted file mode 100644
index 0ca32192..00000000
--- a/sequence/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-Sequence
-========
-
-Simple sequence abstract datatype, intended to transfer a finite number of
-elements from one data structure to another. Some transformations on sequences,
-like `filter`, `map`, `take`, `drop` and `append` can be performed before the
-sequence is iterated/folded on.
-
-Sequence is not designed to be as general-purpose or flexible as, say,
-Batteries' `Enum.t`. Rather, it aims at providing a very simple and efficient
-way of iterating on a finite number of values, only allocating (most of the time)
-one intermediate closure to do so. For instance, iterating on keys, or values,
-of a `Hashtbl.t`, without creating a list.
-
-Documentation
-=============
-
-See [the online API](http://cedeela.fr/~simon/software/sequence/Sequence.html).
-
-Build
-=====
-
-1. via opam `opam install sequence`
-2. manually (need OCaml >= 3.12): `make all install`
-
-If you have `OUnit` installed, you can build and run tests with
-
- $ make tests
- $ ./run_tests.native
-
-If you have `Bench` installed, you can build and run benchmarks with
-
- $ make benchs
- $ ./benchs.native
-
-To see how to use the library, check the `examples` directory.
-`tests.ml` has a few examples of how to convert basic data structures into
-sequences, and conversely.
-
-Examples
-========
-
-The module `examples/sexpr.mli` exposes the interface of the S-expression
-example library. It requires OCaml>=4.0 to compile, because of the GADT
-structure used in the monadic parser combinators part of `examples/sexpr.ml`.
-
-License
-=======
-
-Sequence is available under the BSD license.
diff --git a/sequence/_oasis b/sequence/_oasis
deleted file mode 100644
index b84e7253..00000000
--- a/sequence/_oasis
+++ /dev/null
@@ -1,102 +0,0 @@
-OASISFormat: 0.4
-Name: sequence
-Version: dev
-Homepage: https://github.com/c-cube/sequence
-Authors: Simon Cruanes
-License: BSD-2-clause
-LicenseFile: LICENSE
-Plugins: META (0.3), DevFiles (0.3)
-BuildTools: ocamlbuild
-
-Synopsis: Simple sequence (iterator) datatype and combinators
-Description:
- Simple sequence datatype, intended to transfer a finite number of
- elements from one data structure to another. Some transformations on sequences,
- like `filter`, `map`, `take`, `drop` and `append` can be performed before the
- sequence is iterated/folded on.
-
-Flag bench
- Description: enable benchmarks (require library Benchmark)
- Default: false
-
-Flag invert
- Description: build sequence.invert (requires Delimcc)
- Default: false
-
-Flag bigarray
- Description: build sequence.bigarray (requires bigarray)
- Default: true
-
-Library "sequence"
- Path: .
- Modules: Sequence
- BuildDepends: bytes
-
-Library "invert"
- Path: invert
- Build$: flag(invert)
- Install$: flag(invert)
- Modules: SequenceInvert
- FindlibName: invert
- FindlibParent: sequence
- BuildDepends: sequence,delimcc
-
-Library "bigarray"
- Path: bigarray
- Build$: flag(bigarray)
- Install$: flag(bigarray)
- Modules: SequenceBigarray
- FindlibName: bigarray
- FindlibParent: sequence
- BuildDepends: sequence,bigarray
-
-Document sequence
- Title: Sequence docs
- Type: ocamlbuild (0.3)
- BuildTools+: ocamldoc
- Install: true
- XOCamlbuildPath: .
- XOCamlbuildLibraries: sequence
-
-Test all
- Type: custom
- Command: make run-tests
- TestTools: run_tests
- Run$: flag(tests)
-
-Executable run_tests
- Path: tests/
- Install: false
- CompiledObject: native
- MainIs: run_tests.ml
- Build$: flag(tests)
- BuildDepends: sequence,oUnit
-
-Executable benchs
- Path: bench
- Install: false
- CompiledObject: native
- Build$: flag(bench)
- BuildDepends: sequence,benchmark
- MainIs: benchs.ml
-
-Executable bench_persistent
- Path: bench
- Install: false
- CompiledObject: native
- Build$: flag(bench)
- BuildDepends: sequence,benchmark
- MainIs: bench_persistent.ml
-
-Executable bench_persistent_read
- Path: bench
- Install: false
- CompiledObject: native
- Build$: flag(bench)
- BuildDepends: sequence,benchmark
- MainIs: bench_persistent_read.ml
-
-SourceRepository head
- Type: git
- Location: https://github.com/c-cube/sequence
- Browser: https://github.com/c-cube/sequence/tree/master/src
diff --git a/sequence/_tags b/sequence/_tags
deleted file mode 100644
index a9971c20..00000000
--- a/sequence/_tags
+++ /dev/null
@@ -1,31 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: ffd3fbaf00b431777fea1b8279203bf9)
-# Ignore VCS directories, you can use the same kind of rule outside
-# OASIS_START/STOP if you want to exclude directories that contains
-# useless stuff for the build process
-<**/.svn>: -traverse
-<**/.svn>: not_hygienic
-".bzr": -traverse
-".bzr": not_hygienic
-".hg": -traverse
-".hg": not_hygienic
-".git": -traverse
-".git": not_hygienic
-"_darcs": -traverse
-"_darcs": not_hygienic
-# Library sequence
-"sequence.cmxs": use_sequence
-# Executable benchs
-"bench/benchs.native": pkg_benchmark
-"bench/benchs.native": use_sequence
-# Executable bench_persistent
-"bench/bench_persistent.native": pkg_benchmark
-"bench/bench_persistent.native": use_sequence
-# Executable bench_persistent_read
-"bench/bench_persistent_read.native": pkg_benchmark
-"bench/bench_persistent_read.native": use_sequence
-: pkg_benchmark
-: use_sequence
-# OASIS_STOP
-true: bin_annot
-<**/*.ml>: warn_A, warn(-4)
diff --git a/sequence/bench/bench_persistent.ml b/sequence/bench/bench_persistent.ml
deleted file mode 100644
index 022b6b37..00000000
--- a/sequence/bench/bench_persistent.ml
+++ /dev/null
@@ -1,128 +0,0 @@
-module MList = struct
- type 'a t = {
- content : 'a array; (* elements of the node *)
- mutable len : int; (* number of elements in content *)
- mutable tl : 'a t; (* tail *)
- } (** A list that contains some elements, and may point to another list *)
-
- let _empty () : 'a t = Obj.magic 0
- (** Empty list, for the tl field *)
-
- let make n =
- assert (n > 0);
- { content = Array.make n (Obj.magic 0);
- len = 0;
- tl = _empty ();
- }
-
- let rec is_empty l =
- l.len = 0 && (l.tl == _empty () || is_empty l.tl)
-
- let rec iter f l =
- for i = 0 to l.len - 1 do f l.content.(i); done;
- if l.tl != _empty () then iter f l.tl
-
- let iteri f l =
- let rec iteri i f l =
- for j = 0 to l.len - 1 do f (i+j) l.content.(j); done;
- if l.tl != _empty () then iteri (i+l.len) f l.tl
- in iteri 0 f l
-
- let rec iter_rev f l =
- (if l.tl != _empty () then iter_rev f l.tl);
- for i = l.len - 1 downto 0 do f l.content.(i); done
-
- let length l =
- let rec len acc l =
- if l.tl == _empty () then acc+l.len else len (acc+l.len) l.tl
- in len 0 l
-
- (** Get element by index *)
- let rec get l i =
- if i < l.len then l.content.(i)
- else if i >= l.len && l.tl == _empty () then raise (Invalid_argument "MList.get")
- else get l.tl (i - l.len)
-
- (** Push [x] at the end of the list. It returns the block in which the
- element is inserted. *)
- let rec push x l =
- if l.len = Array.length l.content
- then begin (* insert in the next block *)
- (if l.tl == _empty () then
- let n = Array.length l.content in
- l.tl <- make (n + n lsr 1));
- push x l.tl
- end else begin (* insert in l *)
- l.content.(l.len) <- x;
- l.len <- l.len + 1;
- l
- end
-
- (** Reverse list (in place), and returns the new head *)
- let rev l =
- let rec rev prev l =
- (* reverse array *)
- for i = 0 to (l.len-1) / 2 do
- let x = l.content.(i) in
- l.content.(i) <- l.content.(l.len - i - 1);
- l.content.(l.len - i - 1) <- x;
- done;
- (* reverse next block *)
- let l' = l.tl in
- l.tl <- prev;
- if l' == _empty () then l else rev l l'
- in
- rev (_empty ()) l
-
- (** Build a MList of elements of the Seq. The optional argument indicates
- the size of the blocks *)
- let of_seq ?(size=8) seq =
- (* read sequence into a MList.t *)
- let start = make size in
- let l = ref start in
- seq (fun x -> l := push x !l);
- start
-
- let to_seq l =
- fun k -> iter k l
-end
-
-(** Store content of the seqerator in an enum *)
-let persistent_mlist seq =
- let l = MList.of_seq seq in
- MList.to_seq l
-
-let bench_mlist n =
- for i = 0 to 100 do
- let _ = persistent_mlist Sequence.(1 -- n) in
- ()
- done
-
-let bench_naive n =
- for i = 0 to 100 do
- let l = Sequence.to_rev_list Sequence.(1 -- n) in
- let _ = Sequence.of_list (List.rev l) in
- ()
- done
-
-let bench_current n =
- for i = 0 to 100 do
- let _ = Sequence.persistent Sequence.(1 -- n) in
- ()
- done
-
-let () =
- let bench_n n =
- Printf.printf "BENCH for %d\n" n;
- let res = Benchmark.throughputN 5
- [ "mlist", bench_mlist, n
- ; "naive", bench_naive, n
- ; "current", bench_current, n
- ]
- in Benchmark.tabulate res
- in
- bench_n 100;
- bench_n 100_000;
- ()
-
-(* vim:Use benchmark: *)
diff --git a/sequence/bench/bench_persistent_read.ml b/sequence/bench/bench_persistent_read.ml
deleted file mode 100644
index 8e0dea66..00000000
--- a/sequence/bench/bench_persistent_read.ml
+++ /dev/null
@@ -1,139 +0,0 @@
-module MList = struct
- type 'a t = {
- content : 'a array; (* elements of the node *)
- mutable len : int; (* number of elements in content *)
- mutable tl : 'a t; (* tail *)
- } (** A list that contains some elements, and may point to another list *)
-
- let _empty () : 'a t = Obj.magic 0
- (** Empty list, for the tl field *)
-
- let make n =
- assert (n > 0);
- { content = Array.make n (Obj.magic 0);
- len = 0;
- tl = _empty ();
- }
-
- let rec is_empty l =
- l.len = 0 && (l.tl == _empty () || is_empty l.tl)
-
- let rec iter f l =
- for i = 0 to l.len - 1 do f l.content.(i); done;
- if l.tl != _empty () then iter f l.tl
-
- let iteri f l =
- let rec iteri i f l =
- for j = 0 to l.len - 1 do f (i+j) l.content.(j); done;
- if l.tl != _empty () then iteri (i+l.len) f l.tl
- in iteri 0 f l
-
- let rec iter_rev f l =
- (if l.tl != _empty () then iter_rev f l.tl);
- for i = l.len - 1 downto 0 do f l.content.(i); done
-
- let length l =
- let rec len acc l =
- if l.tl == _empty () then acc+l.len else len (acc+l.len) l.tl
- in len 0 l
-
- (** Get element by index *)
- let rec get l i =
- if i < l.len then l.content.(i)
- else if i >= l.len && l.tl == _empty () then raise (Invalid_argument "MList.get")
- else get l.tl (i - l.len)
-
- (** Push [x] at the end of the list. It returns the block in which the
- element is inserted. *)
- let rec push x l =
- if l.len = Array.length l.content
- then begin (* insert in the next block *)
- (if l.tl == _empty () then
- let n = Array.length l.content in
- l.tl <- make (n + n lsr 1));
- push x l.tl
- end else begin (* insert in l *)
- l.content.(l.len) <- x;
- l.len <- l.len + 1;
- l
- end
-
- (** Reverse list (in place), and returns the new head *)
- let rev l =
- let rec rev prev l =
- (* reverse array *)
- for i = 0 to (l.len-1) / 2 do
- let x = l.content.(i) in
- l.content.(i) <- l.content.(l.len - i - 1);
- l.content.(l.len - i - 1) <- x;
- done;
- (* reverse next block *)
- let l' = l.tl in
- l.tl <- prev;
- if l' == _empty () then l else rev l l'
- in
- rev (_empty ()) l
-
- (** Build a MList of elements of the Seq. The optional argument indicates
- the size of the blocks *)
- let of_seq ?(size=8) seq =
- (* read sequence into a MList.t *)
- let start = make size in
- let l = ref start in
- seq (fun x -> l := push x !l);
- start
-
- let to_seq l =
- fun k -> iter k l
-end
-
-(** Store content of the seqerator in an enum *)
-let persistent_mlist seq =
- let l = MList.of_seq seq in
- MList.to_seq l
-
-let bench_mlist n =
- persistent_mlist Sequence.(1 -- n)
-
-let bench_list n =
- let l = Sequence.to_rev_list Sequence.(1 -- n) in
- Sequence.of_list (List.rev l)
-
-let bench_naive n =
- let s = Sequence.(1 -- n) in
- Sequence.iter ignore s ;
- s
-
-let bench_current n =
- Sequence.persistent Sequence.(1 -- n)
-
-let bench_array n =
- let a = Sequence.to_array Sequence.(1 -- n) in
- Sequence.of_array a
-
-let read s =
- Sequence.map (fun x -> x + 1) s
-
-let () =
- let bench_n n =
- Printf.printf "BENCH for %d\n" n;
- let res =
- let mlist = bench_mlist n in
- let list = bench_list n in
- let current = bench_current n in
- let array = bench_current n in
- let naive = bench_naive n in
- Benchmark.throughputN 5
- [ "mlist", read, mlist
- ; "list", read, list
- ; "current", read, current
- ; "array", read, array
- ; "naive", read, naive
- ]
- in Benchmark.tabulate res
- in
- bench_n 100;
- bench_n 100_000;
- ()
-
-(* vim:Use benchmark: *)
diff --git a/sequence/bench/benchs.ml b/sequence/bench/benchs.ml
deleted file mode 100644
index af8b5db9..00000000
--- a/sequence/bench/benchs.ml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-module S = Sequence
-open Sequence.Infix
-
-let small = [10;20;50;100;500]
-let medium = small @ [1000;10_000;100_000]
-let big = medium @ [500_000; 1_000_000; 2_000_000]
-
-let bench_fold n =
- 0 -- n |> S.fold (+) 0 |> ignore
-
-let bench_flatmap n =
- 0 -- n |> S.flatMap (fun i -> i -- (i+5)) |> (fun _ -> ())
-
-let bench_product n =
- S.product (0 -- n) (0 -- n) (fun (i,j) -> ())
-
-let _ =
- List.iter
- (fun (name,bench,sizes) ->
- Format.printf "-------------------------------------------------------@.";
- Format.printf "bench %s@." name;
- List.iter
- (fun n ->
- let name = name ^ " on " ^ string_of_int n in
- let res = Benchmark.throughput1 2 ~name bench n in
- Benchmark.tabulate res;
- ) sizes
- )
- [ "fold", bench_fold, big
- ; "flatmap", bench_flatmap, medium
- ; "product", bench_product, small
- ];
- ()
diff --git a/sequence/bench/simple_bench.ml b/sequence/bench/simple_bench.ml
deleted file mode 100644
index 96611d7b..00000000
--- a/sequence/bench/simple_bench.ml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-open Sequence.Infix
-
-let _ =
- let n = int_of_string Sys.argv.(1) in
- let seq = 0 -- n in
- let start = Unix.gettimeofday () in
- seq |> Sequence.persistent |> Sequence.fold (+) 0 |> ignore;
- let stop = Unix.gettimeofday () in
- Format.printf "iter on %d: %.4f@." n (stop -. start);
- ()
diff --git a/sequence/bigarray/sequenceBigarray.ml b/sequence/bigarray/sequenceBigarray.ml
deleted file mode 100644
index fd61b86b..00000000
--- a/sequence/bigarray/sequenceBigarray.ml
+++ /dev/null
@@ -1,45 +0,0 @@
-(*
-Copyright (c) 2014, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Interface and Helpers for bigarrays} *)
-
-let of_bigarray b yield =
- let len = Bigarray.Array1.dim b in
- for i=0 to len-1 do
- yield b.{i}
- done
-
-let mmap filename =
- fun yield ->
- let fd = Unix.openfile filename [Unix.O_RDONLY] 0 in
- let len = Unix.lseek fd 0 Unix.SEEK_END in
- let _ = Unix.lseek fd 0 Unix.SEEK_SET in
- let b = Bigarray.Array1.map_file fd Bigarray.Char Bigarray.C_layout false len in
- try
- of_bigarray b yield;
- Unix.close fd
- with e ->
- Unix.close fd;
- raise e
diff --git a/sequence/bigarray/sequenceBigarray.mli b/sequence/bigarray/sequenceBigarray.mli
deleted file mode 100644
index a9c78808..00000000
--- a/sequence/bigarray/sequenceBigarray.mli
+++ /dev/null
@@ -1,34 +0,0 @@
-(*
-Copyright (c) 2014, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Interface and Helpers for bigarrays}
-
-@since 0.5.4 *)
-
-val of_bigarray : ('a, _, _) Bigarray.Array1.t -> 'a Sequence.t
-(** Iterate on the elements of a 1-D array *)
-
-val mmap : string -> char Sequence.t
-(** Map the file into memory, and read the characters. *)
diff --git a/sequence/configure b/sequence/configure
deleted file mode 100755
index 6acfaeb9..00000000
--- a/sequence/configure
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-# OASIS_START
-# DO NOT EDIT (digest: dc86c2ad450f91ca10c931b6045d0499)
-set -e
-
-FST=true
-for i in "$@"; do
- if $FST; then
- set --
- FST=false
- fi
-
- case $i in
- --*=*)
- ARG=${i%%=*}
- VAL=${i##*=}
- set -- "$@" "$ARG" "$VAL"
- ;;
- *)
- set -- "$@" "$i"
- ;;
- esac
-done
-
-ocaml setup.ml -configure "$@"
-# OASIS_STOP
diff --git a/sequence/examples/sexpr.ml b/sequence/examples/sexpr.ml
deleted file mode 100644
index 615f468d..00000000
--- a/sequence/examples/sexpr.ml
+++ /dev/null
@@ -1,305 +0,0 @@
-(*
-Zipperposition: a functional superposition prover for prototyping
-Copyright (C) 2012 Simon Cruanes
-
-This is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-*)
-
-(* {1 Basic S-expressions, with printing and parsing} *)
-
-(** S-expression *)
-type t =
- | Atom of string (** An atom *)
- | List of t list (** A list of S-expressions *)
-
-(** Token that compose a Sexpr once serialized *)
-type token = [`Open | `Close | `Atom of string]
-
-(** {2 Traverse a sequence of tokens} *)
-
-(** Iterate on the S-expression, calling the callback with tokens *)
-let rec iter f s = match s with
- | Atom a -> f (`Atom a)
- | List l -> f `Open; iter_list f l; f `Close
-and iter_list f l = match l with
- | [] -> ()
- | x::l' -> iter f x; iter_list f l'
-
-(** Traverse. This yields a sequence of tokens *)
-let traverse s = Sequence.from_iter (fun k -> iter k s)
-
-(** Returns the same sequence of tokens, but during iteration, if
- the structure of the Sexpr corresponding to the sequence
- is wrong (bad parenthesing), Invalid_argument is raised
- and iteration is stoped *)
-let validate seq =
- let depth = ref 0 in
- Sequence.map
- (fun tok -> match tok with
- | `Open -> incr depth; tok
- | `Close -> if !depth = 0
- then raise (Invalid_argument "wrong parenthesing")
- else decr depth; tok
- | _ -> tok)
- seq
-
-(** {2 Text <-> tokens} *)
-
-(** Lex: create a sequence of tokens from the given in_channel. *)
-let lex input =
- let seq_fun k =
- let in_word = ref false in
- let buf = Buffer.create 128 in
- (* loop. TODO handle escaping of (), and "" *)
- let rec next c =
- match c with
- | '(' -> k `Open
- | ')' -> flush_word(); k `Close
- | ' ' | '\t' | '\n' -> flush_word ()
- | c -> in_word := true; Buffer.add_char buf c
- (* finish the previous word token *)
- and flush_word () =
- if !in_word then begin
- (* this whitespace follows a word *)
- let word = Buffer.contents buf in
- Buffer.clear buf;
- in_word := false;
- k (`Atom word)
- end
- in
- Sequence.iter next input
- in
- Sequence.from_iter seq_fun
-
-(** Build a Sexpr from a sequence of tokens *)
-let of_seq seq =
- (* called on every token *)
- let rec k stack token = match token with
- | `Open -> `Open :: stack
- | `Close -> collapse [] stack
- | `Atom a -> (`Expr (Atom a)) :: stack
- (* collapse last list into an `Expr *)
- and collapse acc stack = match stack with
- | `Open::stack' -> `Expr (List acc) :: stack'
- | `Expr a::stack' -> collapse (a :: acc) stack'
- | _ -> assert false
- in
- (* iterate on the sequence, given an empty initial stack *)
- let stack = Sequence.fold k [] seq in
- (* stack should contain exactly one expression *)
- match stack with
- | [`Expr expr] -> expr
- | [] -> failwith "no Sexpr could be parsed"
- | _ -> failwith "too many elements on the stack"
-
-(** {2 Printing} *)
-
-(** Print a token on the given formatter *)
-let pp_token formatter token = match token with
- | `Open -> Format.fprintf formatter "@[("
- | `Close -> Format.fprintf formatter ")@]"
- | `Atom s -> Format.pp_print_string formatter s
-
-(** Print a sequence of Sexpr tokens on the given formatter *)
-let pp_tokens formatter tokens =
- let first = ref true in
- let last = ref false in
- Sequence.iter
- (fun token ->
- (match token with
- | `Open -> (if not !first then Format.fprintf formatter " "); first := true
- | `Close -> first := false; last := true
- | _ -> if !first then first := false else Format.fprintf formatter " ");
- pp_token formatter token;
- if !last then last := false)
- tokens
-
-(** Pretty-print the S-expr. If [indent] is true, the S-expression
- is printed with indentation. *)
-let pp_sexpr ?(indent=false) formatter s =
- if indent
- then Format.fprintf formatter "@[%a@]" pp_tokens (traverse s)
- else pp_tokens formatter (traverse s)
-
-(** {2 Serializing} *)
-
-let output_seq name subexpr k =
- k `Open;
- k (`Atom name);
- Sequence.iter k subexpr;
- k `Close
-
-let output_str name str k =
- k `Open;
- k (`Atom name);
- k (`Atom str);
- k `Close
-
-(** {2 Parsing} *)
-
-(** Monadic combinators for parsing data from a sequence of tokens,
- without converting to concrete S-expressions.
-
- The [one] parser can raise ParseFailure if it fails to parse
- the atomic type. *)
-
-(** parser that returns a 'a *)
-type 'a parser =
- | Return : 'a -> 'a parser
- | One : (token -> 'a) -> 'a parser
- | Zero : (token -> 'a parser) -> 'a parser
- (* | Maybe of (token -> 'a option) *)
- | Bind : ('b parser * ('b -> 'a parser)) -> 'a parser
- | Fail : string -> 'a parser
-
-exception ParseFailure of string
-
-let (>>=) p f = Bind (p, f)
-
-let (>>) p p' = p >>= fun _ -> p'
-
-let return x = Return x
-
-let fail reason = Fail reason
-
-let one f = One f
-
-let skip = One (fun _ -> ())
-
-let lookahead f = Zero f
-
-let left = One (function | `Open -> ()
- | _ -> raise (ParseFailure "expected '('"))
-
-let right = One (function | `Close -> ()
- | _ -> raise (ParseFailure "expected ')'"))
-
-let pair f g =
- f >>= fun x ->
- g >>= fun y ->
- return (x, y)
-
-let triple f g h =
- f >>= fun x ->
- g >>= fun y ->
- h >>= fun z ->
- return (x, y, z)
-
-(** [(name,p) ^|| p'] behaves as p if the next token is [`Atom name], and
- like [p'] otherwise *)
-let (^||) (name,p) p' =
- lookahead
- (fun token -> match token with
- | `Atom s when s = name -> skip >> p ()
- | _ -> p')
-
-(** Maps the value returned by the parser *)
-let map p f = p >>= fun x -> return (f x)
-
-let p_str = one
- (function | `Atom s -> s | _ -> raise (ParseFailure "expected string"))
-
-let p_int = one
- (function | `Atom s -> (try int_of_string s
- with Failure _ -> raise (ParseFailure "expected int"))
- | _ -> raise (ParseFailure "expected int"))
-
-let p_bool = one
- (function | `Atom s -> (try bool_of_string s
- with Failure _ -> raise (ParseFailure "expected bool"))
- | _ -> raise (ParseFailure "expected bool"))
-
-let p_float = one
- (function | `Atom s -> (try float_of_string s
- with Failure _ -> raise (ParseFailure "expected float"))
- | _ -> raise (ParseFailure "expected float"))
-
-let many p =
- let rec elements token =
- match token with
- | `Close -> return []
- | _ ->
- p >>= fun x ->
- lookahead elements >>= fun l ->
- return (x :: l)
- in
- left >> lookahead elements >>= fun l -> right >> return l
-
-let many1 p =
- p >>= fun x ->
- many p >>= fun l ->
- return (x::l)
-
-(** parsing state that returns a 'a *)
-type 'a state =
- | Bottom : 'a state
- | Push : ('b parser * ('b -> 'a state)) -> 'a state
-
-(** Actually parse the sequence of tokens, with a callback to be called
- on every parsed value. The callback decides whether to push another
- state or whether to continue. *)
-let parse_k p tokens k =
- let rec state = Push(p, fun x -> match k x with `Stop -> Bottom | `Continue -> state) in
- (* Token handler. It also takes the current parser. *)
- let rec one_step state token =
- match reduce state with
- | Bottom -> (* should not happen, unless there are too many tokens *)
- raise (ParseFailure "unexpected ')'")
- | Push (Return _, cont) ->
- assert false (* should be reduced *)
- | Push (Zero f, cont) ->
- let p' = f token in
- let state' = Push (p', cont) in
- one_step state' token (* do not consume token *)
- | Push (One f, cont) ->
- let x = f token in
- let state' = cont x in
- reduce state' (* consume token *)
- (* | Maybe f, _ -> let x = f token in (Obj.magic cont) x *)
- | Push (Bind (p', cont'), cont) ->
- let cont'' x =
- let p'' = cont' x in
- Push (p'', cont)
- in
- let state' = Push (p', cont'') in
- one_step state' token (* do not consume token *)
- | Push (Fail reason, _) -> raise (ParseFailure reason)
- (* Reduce parser state *)
- and reduce state = match state with
- | Push (Return x, cont) ->
- let state' = cont x in
- reduce state'
- | _ -> state
- in
- (* iterate on the tokens *)
- ignore (Sequence.fold one_step state tokens)
-
-(** Parse one value *)
-let parse p tokens =
- let res = ref None in
- parse_k p tokens (fun x -> res := Some x; `Stop);
- (* return result *)
- match !res with
- | None -> raise (ParseFailure "incomplete input")
- | Some x -> x
-
-(** Parse a sequence of values *)
-let parse_seq p tokens =
- let seq_fun k =
- parse_k p tokens (fun x -> k x; `Continue)
- in
- Sequence.from_iter seq_fun
-
diff --git a/sequence/examples/sexpr.mli b/sequence/examples/sexpr.mli
deleted file mode 100644
index 6a8a53c0..00000000
--- a/sequence/examples/sexpr.mli
+++ /dev/null
@@ -1,132 +0,0 @@
-(*
-Zipperposition: a functional superposition prover for prototyping
-Copyright (C) 2012 Simon Cruanes
-
-This is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-*)
-
-(* {1 Basic S-expressions, with printing and parsing} *)
-
-type t =
- | Atom of string (** An atom *)
- | List of t list (** A list of S-expressions *)
- (** S-expression *)
-
-type token = [`Open | `Close | `Atom of string]
- (** Token that compose a Sexpr once serialized *)
-
-(** {2 Traverse a sequence of tokens} *)
-
-val iter : (token -> unit) -> t -> unit
- (** Iterate on the S-expression, calling the callback with tokens *)
-
-val traverse : t -> token Sequence.t
- (** Traverse. This yields a sequence of tokens *)
-
-val validate : token Sequence.t -> token Sequence.t
- (** Returns the same sequence of tokens, but during iteration, if
- the structure of the Sexpr corresponding to the sequence
- is wrong (bad parenthesing), Invalid_argument is raised
- and iteration is stoped *)
-
-(** {2 Text <-> tokens} *)
-
-val lex : char Sequence.t -> token Sequence.t
- (** Lex: create a sequence of tokens from the given sequence of chars. *)
-
-val of_seq : token Sequence.t -> t
- (** Build a Sexpr from a sequence of tokens, or raise Failure *)
-
-(** {2 Printing} *)
-
-val pp_token : Format.formatter -> token -> unit
- (** Print a token on the given formatter *)
-
-val pp_tokens : Format.formatter -> token Sequence.t -> unit
- (** Print a sequence of Sexpr tokens on the given formatter *)
-
-val pp_sexpr : ?indent:bool -> Format.formatter -> t -> unit
- (** Pretty-print the S-expr. If [indent] is true, the S-expression
- is printed with indentation. *)
-
-(** {2 Serializing} *)
-
-val output_seq : string -> token Sequence.t -> (token -> unit) -> unit
- (** print a pair "(name @,sequence)" *)
-
-val output_str : string -> string -> (token -> unit) -> unit
- (** print a pair "(name str)" *)
-
-(** {2 Parsing} *)
-
-(** Monadic combinators for parsing data from a sequence of tokens,
- without converting to concrete S-expressions. *)
-
-type 'a parser
-
-exception ParseFailure of string
-
-val (>>=) : 'a parser -> ('a -> 'b parser) -> 'b parser
- (** Monadic bind: computes a parser from the result of
- the first parser *)
-
-val (>>) : 'a parser -> 'b parser -> 'b parser
- (** Like (>>=), but ignores the result of the first parser *)
-
-val return : 'a -> 'a parser
- (** Parser that consumes no input and return the given value *)
-
-val fail : string -> 'a parser
- (** Fails parsing with the given message *)
-
-val one : (token -> 'a) -> 'a parser
- (** consumes one token with the function *)
-
-val skip : unit parser
- (** Skip the token *)
-
-val lookahead : (token -> 'a parser) -> 'a parser
- (** choose parser given current token *)
-
-val left : unit parser
- (** Parses a `Open *)
-
-val right : unit parser
- (** Parses a `Close *)
-
-val pair : 'a parser -> 'b parser -> ('a * 'b) parser
-val triple : 'a parser -> 'b parser -> 'c parser -> ('a * 'b * 'c) parser
-
-val (^||) : (string * (unit -> 'a parser)) -> 'a parser -> 'a parser
- (** [(name,p) ^|| p'] behaves as [p ()] if the next token is [`Atom name], and
- like [p'] otherwise *)
-
-val map : 'a parser -> ('a -> 'b) -> 'b parser
- (** Maps the value returned by the parser *)
-
-val p_str : string parser
-val p_int : int parser
-val p_bool : bool parser
-
-val many : 'a parser -> 'a list parser
-val many1 : 'a parser -> 'a list parser
-
-val parse : 'a parser -> token Sequence.t -> 'a
- (** Parses exactly one value from the sequence of tokens. Raises
- ParseFailure if anything goes wrong. *)
-
-val parse_seq : 'a parser -> token Sequence.t -> 'a Sequence.t
- (** Parses a sequence of values *)
diff --git a/sequence/examples/test_sexpr.ml b/sequence/examples/test_sexpr.ml
deleted file mode 100644
index 75de0685..00000000
--- a/sequence/examples/test_sexpr.ml
+++ /dev/null
@@ -1,131 +0,0 @@
-
-(** {2 Test sequences} *)
-
-(** print a list of items using the printing function *)
-let pp_list ?(sep=", ") pp_item formatter l =
- Sequence.pp_seq ~sep pp_item formatter (Sequence.of_list l)
-
-(** Set of integers *)
-module ISet = Set.Make(struct type t = int let compare = compare end)
-let iset = (module ISet : Set.S with type elt = int and type t = ISet.t)
-
-module OrderedString = struct type t = string let compare = compare end
-module SMap = Sequence.Map.Make(OrderedString)
-
-let my_map = SMap.of_seq (Sequence.of_list ["1", 1; "2", 2; "3", 3; "answer", 42])
-
-let sexpr = "(foo bar (bazz quux hello 42) world (zoo foo bar (1 2 (3 4))))"
-
-type term = | Lambda of term | Const of string | Var of int | Apply of term * term
-
-let random_term () =
- let max = 10
- and num = ref 0 in
- let rec build depth =
- if depth > 4 || !num > max then Const (random_const ()) else
- match Random.int 6 with
- | 0 -> if depth > 0 then Var (Random.int depth) else Const (random_const ())
- | 1 -> incr num; Lambda (build (depth+1))
- | 2 -> Const (random_const ())
- | _ -> incr num; Apply ((build depth), (build depth))
- and random_const () = [|"a"; "b"; "c"; "f"; "g"; "h"|].(Random.int 6)
- in build 0
-
-let rec sexpr_of_term t =
- let f t k = match t with
- | Var i -> Sexpr.output_str "var" (string_of_int i) k
- | Lambda t' -> Sexpr.output_seq "lambda" (sexpr_of_term t') k
- | Apply (t1, t2) -> Sexpr.output_seq "apply" (Sequence.append (sexpr_of_term t1) (sexpr_of_term t2)) k
- | Const s -> Sexpr.output_str "const" s k
- in Sequence.from_iter (f t)
-
-let term_parser =
- let open Sexpr in
- let rec p_term () =
- left >>
- (("lambda", p_lambda) ^|| ("var", p_var) ^|| ("const", p_const) ^||
- ("apply", p_apply) ^|| fail "bad term") >>= fun x ->
- right >> return x
- and p_apply () =
- p_term () >>= fun x ->
- p_term () >>= fun y ->
- return (Apply (x,y))
- and p_var () = p_int >>= fun i -> return (Var i)
- and p_const () = p_str >>= fun s -> return (Const s)
- and p_lambda () = p_term () >>= fun t -> return (Lambda t)
- in p_term ()
-
-let term_of_sexp seq = Sexpr.parse term_parser seq
-
-let test_term () =
- let t = random_term () in
- Format.printf "@[random term: %a@]@." Sexpr.pp_tokens (sexpr_of_term t);
- let tokens = sexpr_of_term t in
- let t' = term_of_sexp tokens in
- Format.printf "@[parsed: %a@]@." Sexpr.pp_tokens (sexpr_of_term t');
- ()
-
-let _ =
- (* lists *)
- let l = [0;1;2;3;4;5;6] in
- let l' = Sequence.to_list
- (Sequence.filter (fun x -> x mod 2 = 0) (Sequence.of_list l)) in
- let l'' = Sequence.to_list
- (Sequence.take 3 (Sequence.drop 1 (Sequence.of_list l))) in
- let h = Hashtbl.create 3 in
- for i = 0 to 5 do
- Hashtbl.add h i (i*i);
- done;
- let l2 = Sequence.to_list
- (Sequence.map (fun (x, y) -> (string_of_int x) ^ " -> " ^ (string_of_int y))
- (Sequence.of_hashtbl h))
- in
- let l3 = Sequence.to_list (Sequence.rev (Sequence.int_range ~start:0 ~stop:42)) in
- let set = List.fold_left (fun set x -> ISet.add x set) ISet.empty [4;3;100;42] in
- let l4 = Sequence.to_list (Sequence.of_set iset set) in
- Format.printf "l=@[[%a]@]@." (pp_list Format.pp_print_int) l;
- Format.printf "l'=@[[%a]@]@." (pp_list Format.pp_print_int) l';
- Format.printf "l''=@[[%a]@]@." (pp_list Format.pp_print_int) l'';
- Format.printf "l2=@[[%a]@]@." (pp_list Format.pp_print_string) l2;
- Format.printf "l3=@[[%a]@]@." (pp_list Format.pp_print_int) l3;
- Format.printf "s={@[%a@]}@." (Sequence.pp_seq Format.pp_print_int) (Sequence.of_set iset set);
- Format.printf "l4=@[[%a]@]@." (pp_list Format.pp_print_int) l4;
- Format.printf "l3[:5]+l4=@[[%a]@]@." (Sequence.pp_seq Format.pp_print_int)
- (Sequence.of_array
- (Sequence.to_array (Sequence.append
- (Sequence.take 5 (Sequence.of_list l3)) (Sequence.of_list l4))));
- (* sequence, persistent, etc *)
- let seq = Sequence.int_range ~start:0 ~stop:100000 in
- let seq' = Sequence.persistent seq in
- let stream = Sequence.to_stream seq' in
- Format.printf "test length [0..100000]: persistent1 %d, stream %d, persistent2 %d"
- (Sequence.length seq') (Sequence.length (Sequence.of_stream stream)) (Sequence.length seq');
- (* maps *)
- Format.printf "@[map: %a@]@."
- (Sequence.pp_seq (fun formatter (k,v) -> Format.fprintf formatter "\"%s\" -> %d" k v))
- (SMap.to_seq my_map);
- let module MyMapSeq = Sequence.Map.Adapt(Map.Make(OrderedString)) in
- let my_map' = MyMapSeq.of_seq (Sequence.of_list ["1", 1; "2", 2; "3", 3; "answer", 42]) in
- Format.printf "@[map: %a@]@."
- (Sequence.pp_seq (fun formatter (k,v) -> Format.fprintf formatter "\"%s\" -> %d" k v))
- (MyMapSeq.to_seq my_map');
- (* sum *)
- let n = 1000000 in
- let sum = Sequence.fold (+) 0 (Sequence.take n (Sequence.repeat 1)) in
- Format.printf "%dx1 = %d@." n sum;
- assert (n=sum);
- (* sexpr *)
- let s = Sexpr.of_seq (Sexpr.lex (Sequence.of_str sexpr)) in
- let s = Sexpr.of_seq (Sequence.map
- (function | `Atom s -> `Atom (String.capitalize s) | tok -> tok)
- (Sexpr.traverse s))
- in
- Format.printf "@[transform @[%s@] into @[%a@]@]@." sexpr (Sexpr.pp_sexpr ~indent:false) s;
- Format.printf "@[ cycle:%a@]@." Sexpr.pp_tokens
- (Sequence.concat (Sequence.take 10 (Sequence.repeat (Sexpr.traverse s))));
- (* sexpr parsing/printing *)
- for i = 0 to 20 do
- Format.printf "%d-th term test@." i;
- test_term ();
- done;
- ()
diff --git a/sequence/invert/.merlin b/sequence/invert/.merlin
deleted file mode 100644
index 3b9a31d9..00000000
--- a/sequence/invert/.merlin
+++ /dev/null
@@ -1,2 +0,0 @@
-REC
-PKG delimcc
diff --git a/sequence/invert/sequenceInvert.ml b/sequence/invert/sequenceInvert.ml
deleted file mode 100644
index 46efc693..00000000
--- a/sequence/invert/sequenceInvert.ml
+++ /dev/null
@@ -1,62 +0,0 @@
-(*
-Copyright (c) 2014, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Interface to Delimcc (Invert control flow)} *)
-
-type 'a gen = unit -> 'a option
-
-type 'a res =
- | Start
- | Yield of 'a
- | Stop
-
-let _ret_none () = None
-let _ret_unit () = ()
-
-let to_gen seq =
- let p = Delimcc.new_prompt () in
- let _next = ref None in
- ignore (Delimcc.push_prompt p
- (fun () ->
- Delimcc.take_subcont p (fun c () -> _next := Some c; Start);
- seq
- (fun x ->
- Delimcc.take_subcont p (fun c () -> _next := Some c; Yield x)
- );
- _next := None;
- Stop
- ));
- (* call next subcont *)
- let rec next () =
- match !_next with
- | None -> None
- | Some f ->
- begin match Delimcc.push_delim_subcont f _ret_unit with
- | Start -> next ()
- | Yield x -> Some x
- | Stop -> None
- end
- in
- next
diff --git a/sequence/invert/sequenceInvert.mli b/sequence/invert/sequenceInvert.mli
deleted file mode 100644
index bd3c8433..00000000
--- a/sequence/invert/sequenceInvert.mli
+++ /dev/null
@@ -1,32 +0,0 @@
-(*
-Copyright (c) 2014, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Interface to Delimcc (Invert control flow)} *)
-
-type 'a gen = unit -> 'a option
-
-val to_gen : 'a Sequence.t -> 'a gen
-(** Use delimited continuations to iterate on the sequence step by step.
- Relatively costly but still useful *)
diff --git a/sequence/myocamlbuild.ml b/sequence/myocamlbuild.ml
deleted file mode 100644
index 1f969666..00000000
--- a/sequence/myocamlbuild.ml
+++ /dev/null
@@ -1,609 +0,0 @@
-(* OASIS_START *)
-(* DO NOT EDIT (digest: 958ece46307b808952e439e1cc47a739) *)
-module OASISGettext = struct
-(* # 22 "src/oasis/OASISGettext.ml" *)
-
-
- let ns_ str =
- str
-
-
- let s_ str =
- str
-
-
- let f_ (str: ('a, 'b, 'c, 'd) format4) =
- str
-
-
- let fn_ fmt1 fmt2 n =
- if n = 1 then
- fmt1^^""
- else
- fmt2^^""
-
-
- let init =
- []
-
-
-end
-
-module OASISExpr = struct
-(* # 22 "src/oasis/OASISExpr.ml" *)
-
-
-
-
-
- open OASISGettext
-
-
- type test = string
-
-
- type flag = string
-
-
- type t =
- | EBool of bool
- | ENot of t
- | EAnd of t * t
- | EOr of t * t
- | EFlag of flag
- | ETest of test * string
-
-
-
- type 'a choices = (t * 'a) list
-
-
- let eval var_get t =
- let rec eval' =
- function
- | EBool b ->
- b
-
- | ENot e ->
- not (eval' e)
-
- | EAnd (e1, e2) ->
- (eval' e1) && (eval' e2)
-
- | EOr (e1, e2) ->
- (eval' e1) || (eval' e2)
-
- | EFlag nm ->
- let v =
- var_get nm
- in
- assert(v = "true" || v = "false");
- (v = "true")
-
- | ETest (nm, vl) ->
- let v =
- var_get nm
- in
- (v = vl)
- in
- eval' t
-
-
- let choose ?printer ?name var_get lst =
- let rec choose_aux =
- function
- | (cond, vl) :: tl ->
- if eval var_get cond then
- vl
- else
- choose_aux tl
- | [] ->
- let str_lst =
- if lst = [] then
- s_ ""
- else
- String.concat
- (s_ ", ")
- (List.map
- (fun (cond, vl) ->
- match printer with
- | Some p -> p vl
- | None -> s_ "")
- lst)
- in
- match name with
- | Some nm ->
- failwith
- (Printf.sprintf
- (f_ "No result for the choice list '%s': %s")
- nm str_lst)
- | None ->
- failwith
- (Printf.sprintf
- (f_ "No result for a choice list: %s")
- str_lst)
- in
- choose_aux (List.rev lst)
-
-
-end
-
-
-# 132 "myocamlbuild.ml"
-module BaseEnvLight = struct
-(* # 22 "src/base/BaseEnvLight.ml" *)
-
-
- module MapString = Map.Make(String)
-
-
- type t = string MapString.t
-
-
- let default_filename =
- Filename.concat
- (Sys.getcwd ())
- "setup.data"
-
-
- let load ?(allow_empty=false) ?(filename=default_filename) () =
- if Sys.file_exists filename then
- begin
- let chn =
- open_in_bin filename
- in
- let st =
- Stream.of_channel chn
- in
- let line =
- ref 1
- in
- let st_line =
- Stream.from
- (fun _ ->
- try
- match Stream.next st with
- | '\n' -> incr line; Some '\n'
- | c -> Some c
- with Stream.Failure -> None)
- in
- let lexer =
- Genlex.make_lexer ["="] st_line
- in
- let rec read_file mp =
- match Stream.npeek 3 lexer with
- | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
- Stream.junk lexer;
- Stream.junk lexer;
- Stream.junk lexer;
- read_file (MapString.add nm value mp)
- | [] ->
- mp
- | _ ->
- failwith
- (Printf.sprintf
- "Malformed data file '%s' line %d"
- filename !line)
- in
- let mp =
- read_file MapString.empty
- in
- close_in chn;
- mp
- end
- else if allow_empty then
- begin
- MapString.empty
- end
- else
- begin
- failwith
- (Printf.sprintf
- "Unable to load environment, the file '%s' doesn't exist."
- filename)
- end
-
-
- let rec var_expand str env =
- let buff =
- Buffer.create ((String.length str) * 2)
- in
- Buffer.add_substitute
- buff
- (fun var ->
- try
- var_expand (MapString.find var env) env
- with Not_found ->
- failwith
- (Printf.sprintf
- "No variable %s defined when trying to expand %S."
- var
- str))
- str;
- Buffer.contents buff
-
-
- let var_get name env =
- var_expand (MapString.find name env) env
-
-
- let var_choose lst env =
- OASISExpr.choose
- (fun nm -> var_get nm env)
- lst
-end
-
-
-# 237 "myocamlbuild.ml"
-module MyOCamlbuildFindlib = struct
-(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
-
-
- (** OCamlbuild extension, copied from
- * http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
- * by N. Pouillard and others
- *
- * Updated on 2009/02/28
- *
- * Modified by Sylvain Le Gall
- *)
- open Ocamlbuild_plugin
-
-
- (* these functions are not really officially exported *)
- let run_and_read =
- Ocamlbuild_pack.My_unix.run_and_read
-
-
- let blank_sep_strings =
- Ocamlbuild_pack.Lexers.blank_sep_strings
-
-
- let exec_from_conf exec =
- let exec =
- let env_filename = Pathname.basename BaseEnvLight.default_filename in
- let env = BaseEnvLight.load ~filename:env_filename ~allow_empty:true () in
- try
- BaseEnvLight.var_get exec env
- with Not_found ->
- Printf.eprintf "W: Cannot get variable %s\n" exec;
- exec
- in
- let fix_win32 str =
- if Sys.os_type = "Win32" then begin
- let buff = Buffer.create (String.length str) in
- (* Adapt for windowsi, ocamlbuild + win32 has a hard time to handle '\\'.
- *)
- String.iter
- (fun c -> Buffer.add_char buff (if c = '\\' then '/' else c))
- str;
- Buffer.contents buff
- end else begin
- str
- end
- in
- fix_win32 exec
-
- let split s ch =
- let buf = Buffer.create 13 in
- let x = ref [] in
- let flush () =
- x := (Buffer.contents buf) :: !x;
- Buffer.clear buf
- in
- String.iter
- (fun c ->
- if c = ch then
- flush ()
- else
- Buffer.add_char buf c)
- s;
- flush ();
- List.rev !x
-
-
- let split_nl s = split s '\n'
-
-
- let before_space s =
- try
- String.before s (String.index s ' ')
- with Not_found -> s
-
- (* ocamlfind command *)
- let ocamlfind x = S[Sh (exec_from_conf "ocamlfind"); x]
-
- (* This lists all supported packages. *)
- let find_packages () =
- List.map before_space (split_nl & run_and_read "ocamlfind list")
-
-
- (* Mock to list available syntaxes. *)
- let find_syntaxes () = ["camlp4o"; "camlp4r"]
-
-
- let well_known_syntax = [
- "camlp4.quotations.o";
- "camlp4.quotations.r";
- "camlp4.exceptiontracer";
- "camlp4.extend";
- "camlp4.foldgenerator";
- "camlp4.listcomprehension";
- "camlp4.locationstripper";
- "camlp4.macro";
- "camlp4.mapgenerator";
- "camlp4.metagenerator";
- "camlp4.profiler";
- "camlp4.tracer"
- ]
-
-
- let dispatch =
- function
- | After_options ->
- (* By using Before_options one let command line options have an higher
- * priority on the contrary using After_options will guarantee to have
- * the higher priority override default commands by ocamlfind ones *)
- Options.ocamlc := ocamlfind & A"ocamlc";
- Options.ocamlopt := ocamlfind & A"ocamlopt";
- Options.ocamldep := ocamlfind & A"ocamldep";
- Options.ocamldoc := ocamlfind & A"ocamldoc";
- Options.ocamlmktop := ocamlfind & A"ocamlmktop";
- Options.ocamlmklib := ocamlfind & A"ocamlmklib"
-
- | After_rules ->
-
- (* When one link an OCaml library/binary/package, one should use
- * -linkpkg *)
- flag ["ocaml"; "link"; "program"] & A"-linkpkg";
-
- (* For each ocamlfind package one inject the -package option when
- * compiling, computing dependencies, generating documentation and
- * linking. *)
- List.iter
- begin fun pkg ->
- let base_args = [A"-package"; A pkg] in
- (* TODO: consider how to really choose camlp4o or camlp4r. *)
- let syn_args = [A"-syntax"; A "camlp4o"] in
- let args =
- (* Heuristic to identify syntax extensions: whether they end in
- ".syntax"; some might not.
- *)
- if Filename.check_suffix pkg "syntax" ||
- List.mem pkg well_known_syntax then
- syn_args @ base_args
- else
- base_args
- in
- flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
- flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
- flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
- flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
- flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
- end
- (find_packages ());
-
- (* Like -package but for extensions syntax. Morover -syntax is useless
- * when linking. *)
- List.iter begin fun syntax ->
- flag ["ocaml"; "compile"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
- flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
- flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
- flag ["ocaml"; "infer_interface"; "syntax_"^syntax] &
- S[A"-syntax"; A syntax];
- end (find_syntaxes ());
-
- (* The default "thread" tag is not compatible with ocamlfind.
- * Indeed, the default rules add the "threads.cma" or "threads.cmxa"
- * options when using this tag. When using the "-linkpkg" option with
- * ocamlfind, this module will then be added twice on the command line.
- *
- * To solve this, one approach is to add the "-thread" option when using
- * the "threads" package using the previous plugin.
- *)
- flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
- flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
- flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
- flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
- flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
- flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
- flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
- flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
-
- | _ ->
- ()
-end
-
-module MyOCamlbuildBase = struct
-(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
-
-
- (** Base functions for writing myocamlbuild.ml
- @author Sylvain Le Gall
- *)
-
-
-
-
-
- open Ocamlbuild_plugin
- module OC = Ocamlbuild_pack.Ocaml_compiler
-
-
- type dir = string
- type file = string
- type name = string
- type tag = string
-
-
-(* # 62 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
-
-
- type t =
- {
- lib_ocaml: (name * dir list * string list) list;
- lib_c: (name * dir * file list) list;
- flags: (tag list * (spec OASISExpr.choices)) list;
- (* Replace the 'dir: include' from _tags by a precise interdepends in
- * directory.
- *)
- includes: (dir * dir list) list;
- }
-
-
- let env_filename =
- Pathname.basename
- BaseEnvLight.default_filename
-
-
- let dispatch_combine lst =
- fun e ->
- List.iter
- (fun dispatch -> dispatch e)
- lst
-
-
- let tag_libstubs nm =
- "use_lib"^nm^"_stubs"
-
-
- let nm_libstubs nm =
- nm^"_stubs"
-
-
- let dispatch t e =
- let env =
- BaseEnvLight.load
- ~filename:env_filename
- ~allow_empty:true
- ()
- in
- match e with
- | Before_options ->
- let no_trailing_dot s =
- if String.length s >= 1 && s.[0] = '.' then
- String.sub s 1 ((String.length s) - 1)
- else
- s
- in
- List.iter
- (fun (opt, var) ->
- try
- opt := no_trailing_dot (BaseEnvLight.var_get var env)
- with Not_found ->
- Printf.eprintf "W: Cannot get variable %s\n" var)
- [
- Options.ext_obj, "ext_obj";
- Options.ext_lib, "ext_lib";
- Options.ext_dll, "ext_dll";
- ]
-
- | After_rules ->
- (* Declare OCaml libraries *)
- List.iter
- (function
- | nm, [], intf_modules ->
- ocaml_lib nm;
- let cmis =
- List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
- intf_modules in
- dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
- | nm, dir :: tl, intf_modules ->
- ocaml_lib ~dir:dir (dir^"/"^nm);
- List.iter
- (fun dir ->
- List.iter
- (fun str ->
- flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir]))
- ["compile"; "infer_interface"; "doc"])
- tl;
- let cmis =
- List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
- intf_modules in
- dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
- cmis)
- t.lib_ocaml;
-
- (* Declare directories dependencies, replace "include" in _tags. *)
- List.iter
- (fun (dir, include_dirs) ->
- Pathname.define_context dir include_dirs)
- t.includes;
-
- (* Declare C libraries *)
- List.iter
- (fun (lib, dir, headers) ->
- (* Handle C part of library *)
- flag ["link"; "library"; "ocaml"; "byte"; tag_libstubs lib]
- (S[A"-dllib"; A("-l"^(nm_libstubs lib)); A"-cclib";
- A("-l"^(nm_libstubs lib))]);
-
- flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
- (S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
-
- flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
- (S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
-
- (* When ocaml link something that use the C library, then one
- need that file to be up to date.
- *)
- dep ["link"; "ocaml"; "program"; tag_libstubs lib]
- [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
-
- dep ["compile"; "ocaml"; "program"; tag_libstubs lib]
- [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
-
- (* TODO: be more specific about what depends on headers *)
- (* Depends on .h files *)
- dep ["compile"; "c"]
- headers;
-
- (* Setup search path for lib *)
- flag ["link"; "ocaml"; "use_"^lib]
- (S[A"-I"; P(dir)]);
- )
- t.lib_c;
-
- (* Add flags *)
- List.iter
- (fun (tags, cond_specs) ->
- let spec = BaseEnvLight.var_choose cond_specs env in
- let rec eval_specs =
- function
- | S lst -> S (List.map eval_specs lst)
- | A str -> A (BaseEnvLight.var_expand str env)
- | spec -> spec
- in
- flag tags & (eval_specs spec))
- t.flags
- | _ ->
- ()
-
-
- let dispatch_default t =
- dispatch_combine
- [
- dispatch t;
- MyOCamlbuildFindlib.dispatch;
- ]
-
-
-end
-
-
-# 594 "myocamlbuild.ml"
-open Ocamlbuild_plugin;;
-let package_default =
- {
- MyOCamlbuildBase.lib_ocaml = [("sequence", [], [])];
- lib_c = [];
- flags = [];
- includes = []
- }
- ;;
-
-let dispatch_default = MyOCamlbuildBase.dispatch_default package_default;;
-
-# 608 "myocamlbuild.ml"
-(* OASIS_STOP *)
-Ocamlbuild_plugin.dispatch dispatch_default;;
diff --git a/sequence/sequence.ml b/sequence/sequence.ml
deleted file mode 100644
index 6c6bd3b8..00000000
--- a/sequence/sequence.ml
+++ /dev/null
@@ -1,787 +0,0 @@
-(*
-Copyright (c) 2013, Simon Cruanes
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Transient iterators, that abstract on a finite sequence of elements.} *)
-
-(** Sequence abstract iterator type *)
-type 'a t = ('a -> unit) -> unit
-
-type 'a sequence = 'a t
-
-type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
- (** Sequence of pairs of values of type ['a] and ['b]. *)
-
-(** Build a sequence from a iter function *)
-let from_iter f = f
-
-let rec from_fun f k = match f () with
- | None -> ()
- | Some x -> k x; from_fun f k
-
-let empty _ = ()
-
-let singleton x k = k x
-let return x k = k x
-let pure f k = k f
-
-let doubleton x y k = k x; k y
-
-let cons x l k = k x; l k
-let snoc l x k = l k; k x
-
-let repeat x k = while true do k x done
-
-let rec iterate f x k =
- k x;
- iterate f (f x) k
-
-let rec forever f k =
- k (f ());
- forever f k
-
-let cycle s k = while true do s k; done
-
-let iter f seq = seq f
-
-let iteri f seq =
- let r = ref 0 in
- seq
- (fun x ->
- f !r x;
- incr r)
-
-let fold f init seq =
- let r = ref init in
- seq (fun elt -> r := f !r elt);
- !r
-
-let foldi f init seq =
- let i = ref 0 in
- let r = ref init in
- seq
- (fun elt ->
- r := f !r !i elt;
- incr i);
- !r
-
-let map f seq k = seq (fun x -> k (f x))
-
-let mapi f seq k =
- let i = ref 0 in
- seq (fun x -> k (f !i x); incr i)
-
-let filter p seq k = seq (fun x -> if p x then k x)
-
-let append s1 s2 k = s1 k; s2 k
-
-let concat s k = s (fun s' -> s' k)
-
-let flatten s = concat s
-
-let flatMap f seq k = seq (fun x -> f x k)
-
-let flat_map = flatMap
-
-let fmap f seq k =
- seq (fun x -> match f x with
- | None -> ()
- | Some y -> k y
- )
-
-let filter_map = fmap
-
-let intersperse elem seq k =
- let first = ref true in
- seq (fun x -> (if !first then first := false else k elem); k x)
-
-(** Mutable unrolled list to serve as intermediate storage *)
-module MList = struct
- type 'a node =
- | Nil
- | Cons of 'a array * int ref * 'a node ref
-
- (* build and call callback on every element *)
- let of_seq_with seq k =
- let start = ref Nil in
- let chunk_size = ref 8 in
- (* fill the list. prev: tail-reference from previous node *)
- let prev, cur = ref start, ref Nil in
- seq
- (fun x ->
- k x; (* callback *)
- match !cur with
- | Nil ->
- let n = !chunk_size in
- if n < 4096 then chunk_size := 2 * !chunk_size;
- cur := Cons (Array.make n x, ref 1, ref Nil)
- | Cons (a,n,next) ->
- assert (!n < Array.length a);
- a.(!n) <- x;
- incr n;
- if !n = Array.length a then begin
- !prev := !cur;
- prev := next;
- cur := Nil
- end
- );
- !prev := !cur;
- !start
-
- let of_seq seq =
- of_seq_with seq (fun _ -> ())
-
- let rec iter f l = match l with
- | Nil -> ()
- | Cons (a, n, tl) ->
- for i=0 to !n - 1 do f a.(i) done;
- iter f !tl
-
- let iteri f l =
- let rec iteri i f l = match l with
- | Nil -> ()
- | Cons (a, n, tl) ->
- for j=0 to !n - 1 do f (i+j) a.(j) done;
- iteri (i+ !n) f !tl
- in iteri 0 f l
-
- let rec iter_rev f l = match l with
- | Nil -> ()
- | Cons (a, n, tl) ->
- iter_rev f !tl;
- for i = !n-1 downto 0 do f a.(i) done
-
- let length l =
- let rec len acc l = match l with
- | Nil -> acc
- | Cons (_, n, tl) -> len (acc+ !n) !tl
- in len 0 l
-
- (** Get element by index *)
- let rec get l i = match l with
- | Nil -> raise (Invalid_argument "MList.get")
- | Cons (a, n, _) when i < !n -> a.(i)
- | Cons (_, n, tl) -> get !tl (i- !n)
-
- let to_seq l k = iter k l
-
- let _to_next arg l =
- let cur = ref l in
- let i = ref 0 in (* offset in cons *)
- let rec get_next _ = match !cur with
- | Nil -> None
- | Cons (_, n, tl) when !i = !n ->
- cur := !tl;
- i := 0;
- get_next arg
- | Cons (a, _, _) ->
- let x = a.(!i) in
- incr i;
- Some x
- in get_next
-
- let to_gen l = _to_next () l
-
- let to_stream l =
- Stream.from (_to_next 42 l) (* 42=magic cookiiiiiie *)
-
- let to_klist l =
- let rec make (l,i) () = match l with
- | Nil -> `Nil
- | Cons (_, n, tl) when i = !n -> make (!tl,0) ()
- | Cons (a, _, _) -> `Cons (a.(i), make (l,i+1))
- in make (l,0)
-end
-
-let persistent seq =
- let l = MList.of_seq seq in
- MList.to_seq l
-
-type 'a lazy_state =
- | LazySuspend
- | LazyCached of 'a t
-
-let persistent_lazy (seq:'a t) =
- let r = ref LazySuspend in
- fun k ->
- match !r with
- | LazyCached seq' -> seq' k
- | LazySuspend ->
- (* here if this traversal is interruted, no caching occurs *)
- let seq' = MList.of_seq_with seq k in
- r := LazyCached (MList.to_seq seq')
-
-let sort ?(cmp=Pervasives.compare) seq =
- (* use an intermediate list, then sort the list *)
- let l = fold (fun l x -> x::l) [] seq in
- let l = List.fast_sort cmp l in
- fun k -> List.iter k l
-
-let group ?(eq=fun x y -> x = y) seq k =
- let cur = ref [] in
- seq (fun x ->
- match !cur with
- | [] -> cur := [x]
- | (y::_) as l when eq x y ->
- cur := x::l (* [x] belongs to the group *)
- | (_::_) as l ->
- k l; (* yield group, and start another one *)
- cur := [x]);
- (* last list *)
- if !cur <> [] then k !cur
-
-let uniq ?(eq=fun x y -> x = y) seq k =
- let has_prev = ref false
- and prev = ref (Obj.magic 0) in (* avoid option type, costly *)
- seq (fun x ->
- if !has_prev && eq !prev x
- then () (* duplicate *)
- else begin
- has_prev := true;
- prev := x;
- k x
- end)
-
-let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq =
- let module S = Set.Make(struct
- type t = elt
- let compare = cmp
- end) in
- let set = fold (fun acc x -> S.add x acc) S.empty seq in
- fun k -> S.iter k set
-
-let product outer inner k =
- outer (fun x ->
- inner (fun y -> k (x,y))
- )
-
-let product2 outer inner k =
- outer (fun x ->
- inner (fun y -> k x y)
- )
-
-let join ~join_row s1 s2 k =
- s1 (fun a ->
- s2 (fun b ->
- match join_row a b with
- | None -> ()
- | Some c -> k c
- )
- ) (* yield the combination of [a] and [b] *)
-
-let rec unfoldr f b k = match f b with
- | None -> ()
- | Some (x, b') ->
- k x;
- unfoldr f b' k
-
-let scan f acc seq k =
- k acc;
- let acc = ref acc in
- seq (fun elt -> let acc' = f !acc elt in k acc'; acc := acc')
-
-let max ?(lt=fun x y -> x < y) seq =
- let ret = ref None in
- seq (fun x -> match !ret with
- | None -> ret := Some x
- | Some y -> if lt y x then ret := Some x);
- !ret
-
-let min ?(lt=fun x y -> x < y) seq =
- let ret = ref None in
- seq (fun x -> match !ret with
- | None -> ret := Some x
- | Some y -> if lt x y then ret := Some x);
- !ret
-
-exception ExitHead
-
-let head seq =
- let r = ref None in
- try
- seq (fun x -> r := Some x; raise ExitHead); None
- with ExitHead -> !r
-
-let head_exn seq =
- match head seq with
- | None -> invalid_arg "Sequence.head_exn"
- | Some x -> x
-
-exception ExitTake
-
-let take n seq k =
- let count = ref 0 in
- try
- seq (fun x ->
- if !count = n then raise ExitTake;
- incr count;
- k x;
- )
- with ExitTake -> ()
-
-exception ExitTakeWhile
-
-let take_while p seq k =
- try
- seq (fun x -> if p x then k x else raise ExitTakeWhile)
- with ExitTakeWhile -> ()
-
-let drop n seq k =
- let count = ref 0 in
- seq (fun x -> if !count >= n then k x else incr count)
-
-let drop_while p seq k =
- let drop = ref true in
- seq (fun x ->
- if !drop
- then if p x then () else (drop := false; k x)
- else k x)
-
-let rev seq =
- let l = MList.of_seq seq in
- fun k -> MList.iter_rev k l
-
-exception ExitForall
-
-let for_all p seq =
- try
- seq (fun x -> if not (p x) then raise ExitForall);
- true
- with ExitForall -> false
-
-exception ExitExists
-
-(** Exists there some element satisfying the predicate? *)
-let exists p seq =
- try
- seq (fun x -> if p x then raise ExitExists);
- false
- with ExitExists -> true
-
-let mem ?(eq=(=)) x seq = exists (eq x) seq
-
-exception ExitFind
-
-let find f seq =
- let r = ref None in
- begin try
- seq (fun x -> match f x with
- | None -> ()
- | Some _ as res -> r := res; raise ExitFind
- );
- with ExitFind -> ()
- end;
- !r
-
-let length seq =
- let r = ref 0 in
- seq (fun _ -> incr r);
- !r
-
-exception ExitIsEmpty
-
-let is_empty seq =
- try seq (fun _ -> raise ExitIsEmpty); true
- with ExitIsEmpty -> false
-
-(** {2 Transform a sequence} *)
-
-let empty2 _ = ()
-
-let is_empty2 seq2 =
- try ignore (seq2 (fun _ _ -> raise ExitIsEmpty)); true
- with ExitIsEmpty -> false
-
-let length2 seq2 =
- let r = ref 0 in
- seq2 (fun _ _ -> incr r);
- !r
-
-let zip seq2 k = seq2 (fun x y -> k (x,y))
-
-let unzip seq k = seq (fun (x,y) -> k x y)
-
-let zip_i seq k =
- let r = ref 0 in
- seq (fun x -> let n = !r in incr r; k n x)
-
-let fold2 f acc seq2 =
- let acc = ref acc in
- seq2 (fun x y -> acc := f !acc x y);
- !acc
-
-let iter2 f seq2 = seq2 f
-
-let map2 f seq2 k = seq2 (fun x y -> k (f x y))
-
-let map2_2 f g seq2 k =
- seq2 (fun x y -> k (f x y) (g x y))
-
-(** {2 Basic data structures converters} *)
-
-let to_list seq = List.rev (fold (fun y x -> x::y) [] seq)
-
-let to_rev_list seq = fold (fun y x -> x :: y) [] seq
-
-let of_list l k = List.iter k l
-
-let on_list f l =
- to_list (f (of_list l))
-
-let to_opt = head
-
-let of_opt o k = match o with
- | None -> ()
- | Some x -> k x
-
-let to_array seq =
- let l = MList.of_seq seq in
- let n = MList.length l in
- if n = 0
- then [||]
- else begin
- let a = Array.make n (MList.get l 0) in
- MList.iteri (fun i x -> a.(i) <- x) l;
- a
- end
-
-let of_array a k =
- for i = 0 to Array.length a - 1 do
- k (Array.unsafe_get a i)
- done
-
-let of_array_i a k =
- for i = 0 to Array.length a - 1 do
- k (i, Array.unsafe_get a i)
- done
-
-let of_array2 a k =
- for i = 0 to Array.length a - 1 do
- k i (Array.unsafe_get a i)
- done
-
-let array_slice a i j k =
- assert (i >= 0 && j < Array.length a);
- for idx = i to j do
- k a.(idx); (* iterate on sub-array *)
- done
-
-let of_stream s k = Stream.iter k s
-
-let to_stream seq =
- let l = MList.of_seq seq in
- MList.to_stream l
-
-let to_stack s seq = iter (fun x -> Stack.push x s) seq
-
-let of_stack s k = Stack.iter k s
-
-let to_queue q seq = seq (fun x -> Queue.push x q)
-
-let of_queue q k = Queue.iter k q
-
-let hashtbl_add h seq =
- seq (fun (k,v) -> Hashtbl.add h k v)
-
-let hashtbl_replace h seq =
- seq (fun (k,v) -> Hashtbl.replace h k v)
-
-let to_hashtbl seq =
- let h = Hashtbl.create 3 in
- hashtbl_replace h seq;
- h
-
-let to_hashtbl2 seq2 =
- let h = Hashtbl.create 3 in
- seq2 (fun k v -> Hashtbl.replace h k v);
- h
-
-let of_hashtbl h k = Hashtbl.iter (fun a b -> k (a, b)) h
-
-let of_hashtbl2 h k = Hashtbl.iter k h
-
-let hashtbl_keys h k = Hashtbl.iter (fun a _ -> k a) h
-
-let hashtbl_values h k = Hashtbl.iter (fun _ b -> k b) h
-
-let of_str s k = String.iter k s
-
-let to_str seq =
- let b = Buffer.create 64 in
- iter (fun c -> Buffer.add_char b c) seq;
- Buffer.contents b
-
-let concat_str seq =
- let b = Buffer.create 64 in
- iter (Buffer.add_string b) seq;
- Buffer.contents b
-
-exception OneShotSequence
-
-let of_in_channel ic =
- let first = ref true in
- fun k ->
- if not !first
- then raise OneShotSequence
- else (
- first := false;
- try
- while true do
- let c = input_char ic in k c
- done
- with End_of_file -> ()
- )
-
-let to_buffer seq buf =
- seq (fun c -> Buffer.add_char buf c)
-
-(** Iterator on integers in [start...stop] by steps 1 *)
-let int_range ~start ~stop k =
- for i = start to stop do k i done
-
-let int_range_dec ~start ~stop k =
- for i = start downto stop do k i done
-
-let of_set (type s) (type v) m set =
- let module S = (val m : Set.S with type t = s and type elt = v) in
- fun k -> S.iter k set
-
-let to_set (type s) (type v) m seq =
- let module S = (val m : Set.S with type t = s and type elt = v) in
- fold
- (fun set x -> S.add x set)
- S.empty seq
-
-type 'a gen = unit -> 'a option
-type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
-
-let of_gen g =
- (* consume the generator to build a MList *)
- let rec iter1 k = match g () with
- | None -> ()
- | Some x -> k x; iter1 k
- in
- let l = MList.of_seq iter1 in
- MList.to_seq l
-
-let to_gen seq =
- let l = MList.of_seq seq in
- MList.to_gen l
-
-let rec of_klist l k = match l() with
- | `Nil -> ()
- | `Cons (x,tl) -> k x; of_klist tl k
-
-let to_klist seq =
- let l = MList.of_seq seq in
- MList.to_klist l
-
-(** {2 Functorial conversions between sets and sequences} *)
-
-module Set = struct
- module type S = sig
- include Set.S
- val of_seq : elt sequence -> t
- val to_seq : t -> elt sequence
- val to_list : t -> elt list
- val of_list : elt list -> t
- end
-
- (** Create an enriched Set module from the given one *)
- module Adapt(X : Set.S) : S with type elt = X.elt and type t = X.t = struct
- let to_seq set k = X.iter k set
-
- let of_seq seq = fold (fun set x -> X.add x set) X.empty seq
-
- let to_list set = to_list (to_seq set)
-
- include X
-
- let of_list l = List.fold_left (fun set x -> add x set) empty l
- end
-
- (** Functor to build an extended Set module from an ordered type *)
- module Make(X : Set.OrderedType) = struct
- module MySet = Set.Make(X)
- include Adapt(MySet)
- end
-end
-
-(** {2 Conversion between maps and sequences.} *)
-
-module Map = struct
- module type S = sig
- include Map.S
- val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : (key * 'a) sequence -> 'a t
- val keys : 'a t -> key sequence
- val values : 'a t -> 'a sequence
- val to_list : 'a t -> (key * 'a) list
- val of_list : (key * 'a) list -> 'a t
- end
-
- (** Adapt a pre-existing Map module to make it sequence-aware *)
- module Adapt(M : Map.S) = struct
- let to_seq m = from_iter (fun k -> M.iter (fun x y -> k (x,y)) m)
-
- let of_seq seq = fold (fun m (k,v) -> M.add k v m) M.empty seq
-
- let keys m = from_iter (fun k -> M.iter (fun x _ -> k x) m)
-
- let values m = from_iter (fun k -> M.iter (fun _ y -> k y) m)
-
- let of_list l = of_seq (of_list l)
-
- let to_list x = to_list (to_seq x)
-
- include M
- end
-
- (** Create an enriched Map module, with sequence-aware functions *)
- module Make(V : Map.OrderedType) : S with type key = V.t = struct
- module M = Map.Make(V)
- include Adapt(M)
- end
-end
-
-(** {2 Infinite sequences of random values} *)
-
-let random_int bound = forever (fun () -> Random.int bound)
-
-let random_bool = forever Random.bool
-
-let random_float bound = forever (fun () -> Random.float bound)
-
-let random_array a k =
- assert (Array.length a > 0);
- while true do
- let i = Random.int (Array.length a) in
- k a.(i);
- done
-
-let random_list l = random_array (Array.of_list l)
-
-(** {2 Infix functions} *)
-
-module Infix = struct
- let (--) i j = int_range ~start:i ~stop:j
-
- let (--^) i j = int_range_dec ~start:i ~stop:j
-
- let (>>=) x f = flat_map f x
-
- let (>|=) x f = map f x
-
- let (<*>) funs args k =
- funs (fun f -> args (fun x -> k (f x)))
-
- let (<+>) = append
-end
-
-include Infix
-
-(** {2 Pretty printing of sequences} *)
-
-(** Pretty print a sequence of ['a], using the given pretty printer
- to print each elements. An optional separator string can be provided. *)
-let pp_seq ?(sep=", ") pp_elt formatter seq =
- let first = ref true in
- seq
- (fun x ->
- (if !first then first := false
- else begin
- Format.pp_print_string formatter sep;
- Format.pp_print_cut formatter ();
- end);
- pp_elt formatter x)
-
-let pp_buf ?(sep=", ") pp_elt buf seq =
- let first = ref true in
- seq
- (fun x ->
- if !first then first := false else Buffer.add_string buf sep;
- pp_elt buf x)
-
-let to_string ?sep pp_elt seq =
- let buf = Buffer.create 25 in
- pp_buf ?sep (fun buf x -> Buffer.add_string buf (pp_elt x)) buf seq;
- Buffer.contents buf
-
-(** {2 Basic IO} *)
-
-module IO = struct
- let lines_of ?(mode=0o644) ?(flags=[Open_rdonly]) filename =
- fun k ->
- let ic = open_in_gen flags mode filename in
- try
- while true do
- let line = input_line ic in
- k line
- done
- with
- | End_of_file -> close_in ic
- | e -> close_in_noerr ic; raise e
-
- let chunks_of ?(mode=0o644) ?(flags=[]) ?(size=1024) filename =
- fun k ->
- let ic = open_in_gen flags mode filename in
- try
- let buf = Bytes.create size in
- let n = ref 0 in
- let stop = ref false in
- while not !stop do
- n := 0;
- (* try to read [size] chars. If [input] returns [0] it means
- the end of file, so we stop, but first we yield the current chunk *)
- while !n < size && not !stop do
- let n' = input ic buf !n (size - !n) in
- if n' = 0 then stop := true else n := !n + n';
- done;
- if !n > 0
- then k (Bytes.sub_string buf 0 !n)
- done;
- close_in ic
- with e ->
- close_in_noerr ic;
- raise e
-
- let write_bytes_to ?(mode=0o644) ?(flags=[Open_creat;Open_wronly]) filename seq =
- let oc = open_out_gen flags mode filename in
- try
- seq (fun s -> output oc s 0 (Bytes.length s));
- close_out oc
- with e ->
- close_out oc;
- raise e
-
- let write_to ?mode ?flags filename seq =
- write_bytes_to ?mode ?flags filename (map Bytes.unsafe_of_string seq)
-
- let write_bytes_lines ?mode ?flags filename seq =
- let ret = Bytes.unsafe_of_string "\n" in
- write_bytes_to ?mode ?flags filename (snoc (intersperse ret seq) ret)
-
- let write_lines ?mode ?flags filename seq =
- write_bytes_lines ?mode ?flags filename (map Bytes.unsafe_of_string seq)
-end
diff --git a/sequence/sequence.mldylib b/sequence/sequence.mldylib
deleted file mode 100644
index 2f635d2a..00000000
--- a/sequence/sequence.mldylib
+++ /dev/null
@@ -1,4 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: 3ff39d3acb327553070a64ef0cb321d5)
-Sequence
-# OASIS_STOP
diff --git a/sequence/sequence.mli b/sequence/sequence.mli
deleted file mode 100644
index 677f79ce..00000000
--- a/sequence/sequence.mli
+++ /dev/null
@@ -1,606 +0,0 @@
-(*
-copyright (c) 2013, simon cruanes
-all rights reserved.
-
-redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other materials provided with
-the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*)
-
-(** {1 Simple and Efficient Iterators} *)
-
-(** The iterators are designed to allow easy transfer (mappings) between data
- structures, without defining [n^2] conversions between the [n] types. The
- implementation relies on the assumption that a sequence can be iterated
- on as many times as needed; this choice allows for high performance
- of many combinators. However, for transient iterators, the {!persistent}
- function is provided, storing elements of a transient iterator
- in memory; the iterator can then be used several times (See further).
-
- Note that some combinators also return sequences (e.g. {!group}). The
- transformation is computed on the fly every time one iterates over
- the resulting sequence. If a transformation performs heavy computation,
- {!persistent} can also be used as intermediate storage.
-
- Most functions are {b lazy}, i.e. they do not actually use their arguments
- until their result is iterated on. For instance, if one calls {!map}
- on a sequence, one gets a new sequence, but nothing else happens until
- this new sequence is used (by folding or iterating on it).
-
- If a sequence is built from an iteration function that is {b repeatable}
- (i.e. calling it several times always iterates on the same set of
- elements, for instance List.iter or Map.iter), then
- the resulting {!t} object is also repeatable. For {b one-time iter functions}
- such as iteration on a file descriptor or a {!Stream},
- the {!persistent} function can be used to iterate and store elements in
- a memory structure; the result is a sequence that iterates on the elements
- of this memory structure, cheaply and repeatably. *)
-
-type +'a t = ('a -> unit) -> unit
- (** A sequence of values of type ['a]. If you give it a function ['a -> unit]
- it will be applied to every element of the sequence successively. *)
-
-type +'a sequence = 'a t
-
-type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
- (** Sequence of pairs of values of type ['a] and ['b]. *)
-
-(** {2 Build a sequence} *)
-
-val from_iter : (('a -> unit) -> unit) -> 'a t
- (** Build a sequence from a iter function *)
-
-val from_fun : (unit -> 'a option) -> 'a t
- (** Call the function repeatedly until it returns None. This
- sequence is transient, use {!persistent} if needed! *)
-
-val empty : 'a t
- (** Empty sequence. It contains no element. *)
-
-val singleton : 'a -> 'a t
- (** Singleton sequence, with exactly one element. *)
-
-val doubleton : 'a -> 'a -> 'a t
- (** Sequence with exactly two elements *)
-
-val cons : 'a -> 'a t -> 'a t
- (** [cons x l] yields [x], then yields from [l].
- Same as [append (singleton x) l] *)
-
-val snoc : 'a t -> 'a -> 'a t
- (** Same as {!cons} but yields the element after iterating on [l] *)
-
-val return : 'a -> 'a t
- (** Synonym to {!singleton} *)
-
-val pure : 'a -> 'a t
- (** Synonym to {!singleton} *)
-
-val repeat : 'a -> 'a t
- (** Infinite sequence of the same element. You may want to look
- at {!take} and the likes if you iterate on it. *)
-
-val iterate : ('a -> 'a) -> 'a -> 'a t
- (** [iterate f x] is the infinite sequence [x, f(x), f(f(x)), ...] *)
-
-val forever : (unit -> 'b) -> 'b t
- (** Sequence that calls the given function to produce elements.
- The sequence may be transient (depending on the function), and definitely
- is infinite. You may want to use {!take} and {!persistent}. *)
-
-val cycle : 'a t -> 'a t
- (** Cycle forever through the given sequence. Assume the given sequence can
- be traversed any amount of times (not transient). This yields an
- infinite sequence, you should use something like {!take} not to loop
- forever. *)
-
-(** {2 Consume a sequence} *)
-
-val iter : ('a -> unit) -> 'a t -> unit
- (** Consume the sequence, passing all its arguments to the function.
- Basically [iter f seq] is just [seq f]. *)
-
-val iteri : (int -> 'a -> unit) -> 'a t -> unit
- (** Iterate on elements and their index in the sequence *)
-
-val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
- (** Fold over elements of the sequence, consuming it *)
-
-val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
- (** Fold over elements of the sequence and their index, consuming it *)
-
-val map : ('a -> 'b) -> 'a t -> 'b t
- (** Map objects of the sequence into other elements, lazily *)
-
-val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
- (** Map objects, along with their index in the sequence *)
-
-val for_all : ('a -> bool) -> 'a t -> bool
- (** Do all elements satisfy the predicate? *)
-
-val exists : ('a -> bool) -> 'a t -> bool
- (** Exists there some element satisfying the predicate? *)
-
-val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
- (** Is the value a member of the sequence?
- @param eq the equality predicate to use (default [(=)])
- @since 0.5 *)
-
-val find : ('a -> 'b option) -> 'a t -> 'b option
- (** Find the first element on which the function doesn't return [None]
- @since 0.5 *)
-
-val length : 'a t -> int
- (** How long is the sequence? Forces the sequence. *)
-
-val is_empty : 'a t -> bool
- (** Is the sequence empty? Forces the sequence. *)
-
-(** {2 Transform a sequence} *)
-
-val filter : ('a -> bool) -> 'a t -> 'a t
- (** Filter on elements of the sequence *)
-
-val append : 'a t -> 'a t -> 'a t
- (** Append two sequences. Iterating on the result is like iterating
- on the first, then on the second. *)
-
-val concat : 'a t t -> 'a t
- (** Concatenate a sequence of sequences into one sequence. *)
-
-val flatten : 'a t t -> 'a t
- (** Alias for {!concat} *)
-
-val flatMap : ('a -> 'b t) -> 'a t -> 'b t
- (** Monadic bind. Intuitively, it applies the function to every element of the
- initial sequence, and calls {!concat}. *)
-
-val flat_map : ('a -> 'b t) -> 'a t -> 'b t
- (** Alias to {!flatMap} with a more explicit name
- @since 0.5 *)
-
-val fmap : ('a -> 'b option) -> 'a t -> 'b t
- (** Specialized version of {!flatMap} for options. *)
-
-val filter_map : ('a -> 'b option) -> 'a t -> 'b t
- (** Alias to {!fmap} with a more explicit name
- @since 0.5 *)
-
-val intersperse : 'a -> 'a t -> 'a t
- (** Insert the single element between every element of the sequence *)
-
-(** {2 Caching} *)
-
-val persistent : 'a t -> 'a t
- (** Iterate on the sequence, storing elements in an efficient internal structure..
- The resulting sequence can be iterated on as many times as needed.
- {b Note}: calling persistent on an already persistent sequence
- will still make a new copy of the sequence! *)
-
-val persistent_lazy : 'a t -> 'a t
- (** Lazy version of {!persistent}. When calling [persistent_lazy s],
- a new sequence [s'] is immediately returned (without actually consuming
- [s]) in constant time; the first time [s'] is iterated on,
- it also consumes [s] and caches its content into a inner data
- structure that will back [s'] for future iterations.
-
- {b warning}: on the first traversal of [s'], if the traversal
- is interrupted prematurely ({!take}, etc.) then [s'] will not be
- memorized, and the next call to [s'] will traverse [s] again. *)
-
-(** {2 Misc} *)
-
-val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
- (** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time.
- It iterates on elements of the argument sequence immediately,
- before it sorts them. *)
-
-val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
- (** Sort the sequence and remove duplicates. Eager, same as [sort] *)
-
-val group : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
- (** Group equal consecutive elements. *)
-
-val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
- (** Remove consecutive duplicate elements. Basically this is
- like [fun seq -> map List.hd (group seq)]. *)
-
-val product : 'a t -> 'b t -> ('a * 'b) t
- (** Cartesian product of the sequences. When calling [product a b],
- the caller {b MUST} ensure that [b] can be traversed as many times
- as required (several times), possibly by calling {!persistent} on it
- beforehand. *)
-
-val product2 : 'a t -> 'b t -> ('a, 'b) t2
- (** Binary version of {!product}. Same requirements.
- @since 0.5 *)
-
-val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
- (** [join ~join_row a b] combines every element of [a] with every
- element of [b] using [join_row]. If [join_row] returns None, then
- the two elements do not combine. Assume that [b] allows for multiple
- iterations. *)
-
-val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
- (** [unfoldr f b] will apply [f] to [b]. If it
- yields [Some (x,b')] then [x] is returned
- and unfoldr recurses with [b']. *)
-
-val scan : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b t
- (** Sequence of intermediate results *)
-
-val max : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
- (** Max element of the sequence, using the given comparison function.
- @return None if the sequence is empty, Some [m] where [m] is the maximal
- element otherwise *)
-
-val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
- (** Min element of the sequence, using the given comparison function.
- see {!max} for more details. *)
-
-val head : 'a t -> 'a option
- (** First element, if any, otherwise [None]
- @since 0.5.1 *)
-
-val head_exn : 'a t -> 'a
- (** First element, if any, fails
- @raise Invalid_argument if the sequence is empty
- @since 0.5.1 *)
-
-val take : int -> 'a t -> 'a t
- (** Take at most [n] elements from the sequence. Works on infinite
- sequences. *)
-
-val take_while : ('a -> bool) -> 'a t -> 'a t
- (** Take elements while they satisfy the predicate, then stops iterating.
- Will work on an infinite sequence [s] if the predicate is false for at
- least one element of [s]. *)
-
-val drop : int -> 'a t -> 'a t
- (** Drop the [n] first elements of the sequence. Lazy. *)
-
-val drop_while : ('a -> bool) -> 'a t -> 'a t
- (** Predicate version of {!drop} *)
-
-val rev : 'a t -> 'a t
- (** Reverse the sequence. O(n) memory and time, needs the
- sequence to be finite. The result is persistent and does
- not depend on the input being repeatable. *)
-
-(** {2 Binary sequences} *)
-
-val empty2 : ('a, 'b) t2
-
-val is_empty2 : (_, _) t2 -> bool
-
-val length2 : (_, _) t2 -> int
-
-val zip : ('a, 'b) t2 -> ('a * 'b) t
-
-val unzip : ('a * 'b) t -> ('a, 'b) t2
-
-val zip_i : 'a t -> (int, 'a) t2
- (** Zip elements of the sequence with their index in the sequence *)
-
-val fold2 : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t2 -> 'c
-
-val iter2 : ('a -> 'b -> unit) -> ('a, 'b) t2 -> unit
-
-val map2 : ('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t
-
-val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a, 'b) t2 -> ('c, 'd) t2
- (** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
-
-(** {2 Basic data structures converters} *)
-
-val to_list : 'a t -> 'a list
- (** Convert the sequence into a list. Preserves order of elements.
- This function is tail-recursive, but consumes 2*n memory.
- If order doesn't matter to you, consider {!to_rev_list}. *)
-
-val to_rev_list : 'a t -> 'a list
- (** Get the list of the reversed sequence (more efficient than {!to_list}) *)
-
-val of_list : 'a list -> 'a t
-
-val on_list : ('a t -> 'b t) -> 'a list -> 'b list
-(** [on_list f l] is equivalent to [to_list @@ f @@ of_list l].
- @since 0.5.2
-*)
-
-val to_opt : 'a t -> 'a option
- (** Alias to {!head}
- @since 0.5.1 *)
-
-val to_array : 'a t -> 'a array
- (** Convert to an array. Currently not very efficient because
- an intermediate list is used. *)
-
-val of_array : 'a array -> 'a t
-
-val of_array_i : 'a array -> (int * 'a) t
- (** Elements of the array, with their index *)
-
-val of_array2 : 'a array -> (int, 'a) t2
-
-val array_slice : 'a array -> int -> int -> 'a t
- (** [array_slice a i j] Sequence of elements whose indexes range
- from [i] to [j] *)
-
-val of_opt : 'a option -> 'a t
- (** Iterate on 0 or 1 values.
- @since 0.5.1 *)
-
-val of_stream : 'a Stream.t -> 'a t
- (** Sequence of elements of a stream (usable only once) *)
-
-val to_stream : 'a t -> 'a Stream.t
- (** Convert to a stream. linear in memory and time (a copy is made in memory) *)
-
-val to_stack : 'a Stack.t -> 'a t -> unit
- (** Push elements of the sequence on the stack *)
-
-val of_stack : 'a Stack.t -> 'a t
- (** Sequence of elements of the stack (same order as [Stack.iter]) *)
-
-val to_queue : 'a Queue.t -> 'a t -> unit
- (** Push elements of the sequence into the queue *)
-
-val of_queue : 'a Queue.t -> 'a t
- (** Sequence of elements contained in the queue, FIFO order *)
-
-val hashtbl_add : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
- (** Add elements of the sequence to the hashtable, with
- Hashtbl.add *)
-
-val hashtbl_replace : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
- (** Add elements of the sequence to the hashtable, with
- Hashtbl.replace (erases conflicting bindings) *)
-
-val to_hashtbl : ('a * 'b) t -> ('a, 'b) Hashtbl.t
- (** Build a hashtable from a sequence of key/value pairs *)
-
-val to_hashtbl2 : ('a, 'b) t2 -> ('a, 'b) Hashtbl.t
- (** Build a hashtable from a sequence of key/value pairs *)
-
-val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b) t
- (** Sequence of key/value pairs from the hashtable *)
-
-val of_hashtbl2 : ('a, 'b) Hashtbl.t -> ('a, 'b) t2
- (** Sequence of key/value pairs from the hashtable *)
-
-val hashtbl_keys : ('a, 'b) Hashtbl.t -> 'a t
-val hashtbl_values : ('a, 'b) Hashtbl.t -> 'b t
-
-val of_str : string -> char t
-val to_str : char t -> string
-
-val concat_str : string t -> string
- (** Concatenate strings together, eagerly.
- Also see {!intersperse} to add a separator.
- @since 0.5 *)
-
-exception OneShotSequence
- (** Raised when the user tries to iterate several times on
- a transient iterator *)
-
-val of_in_channel : in_channel -> char t
- (** Iterates on characters of the input (can block when one
- iterates over the sequence). If you need to iterate
- several times on this sequence, use {!persistent}.
- @raise OneShotSequence when used more than once. *)
-
-val to_buffer : char t -> Buffer.t -> unit
- (** Copy content of the sequence into the buffer *)
-
-val int_range : start:int -> stop:int -> int t
- (** Iterator on integers in [start...stop] by steps 1. Also see
- {!(--)} for an infix version. *)
-
-val int_range_dec : start:int -> stop:int -> int t
- (** Iterator on decreasing integers in [stop...start] by steps -1.
- See {!(--^)} for an infix version *)
-
-val of_set : (module Set.S with type elt = 'a and type t = 'b) -> 'b -> 'a t
- (** Convert the given set to a sequence. The set module must be provided. *)
-
-val to_set : (module Set.S with type elt = 'a and type t = 'b) -> 'a t -> 'b
- (** Convert the sequence to a set, given the proper set module *)
-
-type 'a gen = unit -> 'a option
-type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
-
-val of_gen : 'a gen -> 'a t
- (** Traverse eagerly the generator and build a sequence from it *)
-
-val to_gen : 'a t -> 'a gen
- (** Make the sequence persistent (O(n)) and then iterate on it. Eager. *)
-
-val of_klist : 'a klist -> 'a t
- (** Iterate on the lazy list *)
-
-val to_klist : 'a t -> 'a klist
- (** Make the sequence persistent and then iterate on it. Eager. *)
-
-(** {2 Functorial conversions between sets and sequences} *)
-
-module Set : sig
- module type S = sig
- include Set.S
- val of_seq : elt sequence -> t
- val to_seq : t -> elt sequence
- val to_list : t -> elt list
- val of_list : elt list -> t
- end
-
- (** Create an enriched Set module from the given one *)
- module Adapt(X : Set.S) : S with type elt = X.elt and type t = X.t
-
- (** Functor to build an extended Set module from an ordered type *)
- module Make(X : Set.OrderedType) : S with type elt = X.t
-end
-
-(** {2 Conversion between maps and sequences.} *)
-
-module Map : sig
- module type S = sig
- include Map.S
- val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : (key * 'a) sequence -> 'a t
- val keys : 'a t -> key sequence
- val values : 'a t -> 'a sequence
- val to_list : 'a t -> (key * 'a) list
- val of_list : (key * 'a) list -> 'a t
- end
-
- (** Adapt a pre-existing Map module to make it sequence-aware *)
- module Adapt(M : Map.S) : S with type key = M.key and type 'a t = 'a M.t
-
- (** Create an enriched Map module, with sequence-aware functions *)
- module Make(V : Map.OrderedType) : S with type key = V.t
-end
-
-(** {2 Infinite sequences of random values} *)
-
-val random_int : int -> int t
- (** Infinite sequence of random integers between 0 and
- the given higher bound (see Random.int) *)
-
-val random_bool : bool t
- (** Infinite sequence of random bool values *)
-
-val random_float : float -> float t
-
-val random_array : 'a array -> 'a t
- (** Sequence of choices of an element in the array *)
-
-val random_list : 'a list -> 'a t
- (** Infinite sequence of random elements of the list. Basically the
- same as {!random_array}. *)
-
-(** {2 Infix functions} *)
-
-module Infix : sig
- val (--) : int -> int -> int t
- (** [a -- b] is the range of integers from [a] to [b], both included,
- in increasing order. It will therefore be empty if [a > b]. *)
-
- val (--^) : int -> int -> int t
- (** [a --^ b] is the range of integers from [b] to [a], both included,
- in decreasing order (starts from [a]).
- It will therefore be empty if [a < b]. *)
-
- val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
- (** Monadic bind (infix version of {!flat_map}
- @since 0.5 *)
-
- val (>|=) : 'a t -> ('a -> 'b) -> 'b t
- (** Infix version of {!map}
- @since 0.5 *)
-
- val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
- (** Applicative operator (product+application)
- @since 0.5 *)
-
- val (<+>) : 'a t -> 'a t -> 'a t
- (** Concatenation of sequences
- @since 0.5 *)
-end
-
-include module type of Infix
-
-
-(** {2 Pretty printing of sequences} *)
-
-val pp_seq : ?sep:string -> (Format.formatter -> 'a -> unit) ->
- Format.formatter -> 'a t -> unit
- (** Pretty print a sequence of ['a], using the given pretty printer
- to print each elements. An optional separator string can be provided. *)
-
-val pp_buf : ?sep:string -> (Buffer.t -> 'a -> unit) ->
- Buffer.t -> 'a t -> unit
- (** Print into a buffer *)
-
-val to_string : ?sep:string -> ('a -> string) -> 'a t -> string
- (** Print into a string *)
-
-(** {2 Basic IO}
-
-Very basic interface to manipulate files as sequence of chunks/lines. The
-sequences take care of opening and closing files properly; every time
-one iterates over a sequence, the file is opened/closed again.
-
-Example: copy a file ["a"] into file ["b"], removing blank lines:
-
-{[
- Sequence.(IO.lines_of "a" |> filter (fun l-> l<> "") |> IO.write_lines "b");;
-]}
-
-By chunks of [4096] bytes:
-
-{[
- Sequence.IO.(chunks_of ~size:4096 "a" |> write_to "b");;
-]}
-
-Read the lines of a file into a list:
-
-{[
- Sequence.IO.lines "a" |> Sequence.to_list
-]}
-
-@since 0.5.1 *)
-
-module IO : sig
- val lines_of : ?mode:int -> ?flags:open_flag list ->
- string -> string t
- (** [lines_of filename] reads all lines of the given file. It raises the
- same exception as would opening the file and read from it, except
- from [End_of_file] (which is caught). The file is {b always} properly
- closed.
- Every time the sequence is iterated on, the file is opened again, so
- different iterations might return different results
- @param mode default [0o644]
- @param flags default: [[Open_rdonly]] *)
-
- val chunks_of : ?mode:int -> ?flags:open_flag list -> ?size:int ->
- string -> string t
- (** Read chunks of the given [size] from the file. The last chunk might be
- smaller. Behaves like {!lines_of} regarding errors and options.
- Every time the sequence is iterated on, the file is opened again, so
- different iterations might return different results *)
-
- val write_to : ?mode:int -> ?flags:open_flag list ->
- string -> string t -> unit
- (** [write_to filename seq] writes all strings from [seq] into the given
- file. It takes care of opening and closing the file.
- @param mode default [0o644]
- @param flags used by [open_out_gen]. Default: [[Open_creat;Open_wronly]]. *)
-
- val write_bytes_to : ?mode:int -> ?flags:open_flag list ->
- string -> Bytes.t t -> unit
- (** @since 0.5.4 *)
-
- val write_lines : ?mode:int -> ?flags:open_flag list ->
- string -> string t -> unit
- (** Same as {!write_to}, but intercales ['\n'] between each string *)
-
- val write_bytes_lines : ?mode:int -> ?flags:open_flag list ->
- string -> Bytes.t t -> unit
- (** @since 0.5.4 *)
-end
diff --git a/sequence/sequence.mllib b/sequence/sequence.mllib
deleted file mode 100644
index 2f635d2a..00000000
--- a/sequence/sequence.mllib
+++ /dev/null
@@ -1,4 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: 3ff39d3acb327553070a64ef0cb321d5)
-Sequence
-# OASIS_STOP
diff --git a/sequence/sequence.odocl b/sequence/sequence.odocl
deleted file mode 100644
index 2f635d2a..00000000
--- a/sequence/sequence.odocl
+++ /dev/null
@@ -1,4 +0,0 @@
-# OASIS_START
-# DO NOT EDIT (digest: 3ff39d3acb327553070a64ef0cb321d5)
-Sequence
-# OASIS_STOP
diff --git a/sequence/setup.ml b/sequence/setup.ml
deleted file mode 100644
index fe8169fe..00000000
--- a/sequence/setup.ml
+++ /dev/null
@@ -1,37 +0,0 @@
-(* setup.ml generated for the first time by OASIS v0.4.4 *)
-
-(* OASIS_START *)
-(* DO NOT EDIT (digest: 9852805d5c19ca1cb6abefde2dcea323) *)
-(******************************************************************************)
-(* OASIS: architecture for building OCaml libraries and applications *)
-(* *)
-(* Copyright (C) 2011-2013, Sylvain Le Gall *)
-(* Copyright (C) 2008-2011, OCamlCore SARL *)
-(* *)
-(* This library is free software; you can redistribute it and/or modify it *)
-(* under the terms of the GNU Lesser General Public License as published by *)
-(* the Free Software Foundation; either version 2.1 of the License, or (at *)
-(* your option) any later version, with the OCaml static compilation *)
-(* exception. *)
-(* *)
-(* This library is distributed in the hope that it will be useful, but *)
-(* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *)
-(* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *)
-(* details. *)
-(* *)
-(* You should have received a copy of the GNU Lesser General Public License *)
-(* along with this library; if not, write to the Free Software Foundation, *)
-(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)
-(******************************************************************************)
-
-let () =
- try
- Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
- with Not_found -> ()
-;;
-#use "topfind";;
-#require "oasis.dynrun";;
-open OASISDynRun;;
-
-(* OASIS_STOP *)
-let () = setup ();;
diff --git a/sequence/tests/run_tests.ml b/sequence/tests/run_tests.ml
deleted file mode 100644
index 0fa3d58c..00000000
--- a/sequence/tests/run_tests.ml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-open OUnit
-
-let suite =
- "run_tests" >:::
- [ Test_sequence.suite; ]
-
-let _ =
- OUnit.run_test_tt_main suite
diff --git a/sequence/tests/test_sequence.ml b/sequence/tests/test_sequence.ml
deleted file mode 100644
index 30f0f1c9..00000000
--- a/sequence/tests/test_sequence.ml
+++ /dev/null
@@ -1,235 +0,0 @@
-
-open OUnit
-
-module S = Sequence
-
-let pp_ilist l =
- let b = Buffer.create 15 in
- let fmt = Format.formatter_of_buffer b in
- Format.fprintf fmt "@[%a@]" (S.pp_seq Format.pp_print_int) (S.of_list l);
- Buffer.contents b
-
-let test_empty () =
- let seq = S.empty in
- OUnit.assert_bool "empty" (S.is_empty seq);
- OUnit.assert_bool "empty"
- (try S.iter (fun _ -> raise Exit) seq; true with Exit -> false);
- ()
-
-let test_repeat () =
- let seq = S.repeat "hello" in
- OUnit.assert_equal ["hello"; "hello"; "hello"]
- (seq |> S.take 3 |> S.to_list);
- ()
-
-let test_concat () =
- let s1 = S.(1 -- 5) in
- let s2 = S.(6 -- 10) in
- let l = [1;2;3;4;5;6;7;8;9;10] in
- OUnit.assert_equal l (S.to_list (S.append s1 s2));
- ()
-
-let test_fold () =
- let n = S.(1 -- 10)
- |> S.fold (+) 0 in
- OUnit.assert_equal 55 n;
- ()
-
-let test_foldi () =
- let l = ["hello"; "world"]
- |> S.of_list
- |> S.foldi (fun acc i x -> (i,x) :: acc) [] in
- OUnit.assert_equal [1, "world"; 0, "hello"] l;
- ()
-
-let test_exists () =
- S.(1 -- 100)
- |> S.exists (fun x -> x = 59)
- |> OUnit.assert_bool "exists";
- S.(1 -- 100)
- |> S.exists (fun x -> x < 0)
- |> (fun x -> not x)
- |> OUnit.assert_bool "not exists";
- ()
-
-let test_length () =
- S.(1 -- 1000) |> S.length |> OUnit.assert_equal 1000
-
-let test_concat2 () =
- S.(1 -- 1000)
- |> S.map (fun i -> S.(i -- (i+1)))
- |> S.concat
- |> S.length
- |> OUnit.assert_equal 2000
-
-let test_flatMap () =
- S.(1 -- 1000)
- |> S.flatMap (fun i -> S.(i -- (i+1)))
- |> S.length
- |> OUnit.assert_equal 2000
-
-let test_intersperse () =
- S.(1 -- 100)
- |> (fun seq -> S.intersperse 0 seq)
- |> S.take 10
- |> S.to_list
- |> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0]
-
-let test_not_persistent () =
- let printer = pp_ilist in
- let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
- let seq = S.of_stream stream in
- OUnit.assert_equal ~printer [0;1;2;3;4] (seq |> S.to_list);
- OUnit.assert_equal ~printer [] (seq |> S.to_list);
- ()
-
-let test_persistent () =
- let printer = pp_ilist in
- let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
- let seq = S.of_stream stream in
- (* consume seq into a persistent version of itself *)
- let seq' = S.persistent seq in
- OUnit.assert_equal ~printer [] (seq |> S.to_list);
- OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_list);
- OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_list);
- OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_stream |> S.of_stream |> S.to_list);
- ()
-
-let test_big_persistent () =
- let printer = pp_ilist in
- let seq = S.(0 -- 10_000) in
- let seq' = S.persistent seq in
- OUnit.assert_equal 10_001 (S.length seq');
- OUnit.assert_equal 10_001 (S.length seq');
- OUnit.assert_equal ~printer [0;1;2;3] (seq' |> S.take 4 |> S.to_list);
- ()
-
-let test_sort () =
- S.(1 -- 100)
- |> S.sort ~cmp:(fun i j -> j - i)
- |> S.take 4
- |> S.to_list
- |> OUnit.assert_equal [100;99;98;97]
-
-let test_sort_uniq () =
- [42;1;2;3;4;5;4;3;2;1]
- |> S.of_list
- |> S.sort_uniq ?cmp:None
- |> S.to_list
- |> OUnit.assert_equal [1;2;3;4;5;42]
-
-let test_group () =
- [1;2;3;3;2;2;3;4]
- |> S.of_list |> S.group ?eq:None |> S.to_list
- |> OUnit.assert_equal [[1];[2];[3;3];[2;2];[3];[4]]
-
-let test_uniq () =
- [1;2;2;3;4;4;4;3;3]
- |> S.of_list |> S.uniq ?eq:None |> S.to_list
- |> OUnit.assert_equal [1;2;3;4;3]
-
-let test_product () =
- let stream = Stream.from (fun i -> if i < 3 then Some i else None) in
- let a = S.of_stream stream in
- let b = S.of_list ["a";"b";"c"] in
- let s = S.product a b |> S.map (fun (x,y) -> y,x)
- |> S.to_list |> List.sort compare in
- OUnit.assert_equal ["a",0; "a", 1; "a", 2;
- "b",0; "b", 1; "b", 2;
- "c",0; "c", 1; "c", 2;] s
-
-let test_join () =
- let s1 = S.(1 -- 3) in
- let s2 = S.of_list ["1"; "2"] in
- let join_row i j =
- if string_of_int i = j then Some (string_of_int i ^ " = " ^ j) else None
- in
- let s = S.join ~join_row s1 s2 in
- OUnit.assert_equal ["1 = 1"; "2 = 2"] (S.to_list s);
- ()
-
-let test_scan () =
- S.(1 -- 5)
- |> S.scan (+) 0
- |> S.to_list
- |> OUnit.assert_equal ~printer:pp_ilist [0;1;3;6;10;15]
-
-let test_drop () =
- S.(1 -- 5) |> S.drop 2 |> S.to_list |> OUnit.assert_equal [3;4;5]
-
-let test_rev () =
- S.(1 -- 5) |> S.rev |> S.to_list |> OUnit.assert_equal [5;4;3;2;1]
-
-let test_unfoldr () =
- let f x = if x < 5 then Some (string_of_int x,x+1) else None in
- S.unfoldr f 0
- |> S.to_list
- |> OUnit.assert_equal ["0"; "1"; "2"; "3"; "4"]
-
-let test_hashtbl () =
- let h = S.(1 -- 5)
- |> S.zip_i
- |> S.to_hashtbl2 in
- S.(0 -- 4)
- |> S.iter (fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i));
- OUnit.assert_equal [0;1;2;3;4] (S.hashtbl_keys h |> S.sort ?cmp:None |> S.to_list);
- ()
-
-let test_buff () =
- let b = Buffer.create 4 in
- "hello world"
- |> S.of_str |> S.rev |> S.map Char.uppercase
- |> (fun seq -> S.to_buffer seq b);
- OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
- ()
-
-let test_int_range () =
- OUnit.assert_equal ~printer:pp_ilist [1;2;3;4] S.(to_list (1--4));
- OUnit.assert_equal ~printer:pp_ilist [10;9;8;7;6] S.(to_list (10 --^ 6));
- OUnit.assert_equal ~printer:pp_ilist [] S.(to_list (10--4));
- OUnit.assert_equal ~printer:pp_ilist [] S.(to_list (10 --^ 60));
- ()
-
-let test_take () =
- let l = S.(to_list (take 0 (of_list [1]))) in
- OUnit.assert_equal ~printer:pp_ilist [] l;
- let l = S.(to_list (take 5 (of_list [1;2;3;4;5;6;7;8;9;10]))) in
- OUnit.assert_equal ~printer:pp_ilist [1;2;3;4;5] l;
- ()
-
-let test_regression1 () =
- let s = S.(take 10 (repeat 1)) in
- OUnit.assert_bool "not empty" (not (S.is_empty s));
- ()
-
-let suite =
- "test_sequence" >:::
- [ "test_empty" >:: test_empty;
- "test_repeat" >:: test_repeat;
- "test_concat" >:: test_concat;
- "test_concat2" >:: test_concat2;
- "test_fold" >:: test_fold;
- "test_foldi" >:: test_foldi;
- "test_exists" >:: test_exists;
- "test_length" >:: test_length;
- "test_concat" >:: test_concat;
- "test_flatMap" >:: test_flatMap;
- "test_intersperse" >:: test_intersperse;
- "test_not_persistent" >:: test_not_persistent;
- "test_persistent" >:: test_persistent;
- "test_big_persistent" >:: test_big_persistent;
- "test_sort" >:: test_sort;
- "test_sort_uniq" >:: test_sort;
- "test_group" >:: test_group;
- "test_uniq" >:: test_uniq;
- "test_product" >:: test_product;
- "test_join" >:: test_join;
- "test_scan" >:: test_scan;
- "test_drop" >:: test_drop;
- "test_rev" >:: test_rev;
- "test_unfoldr" >:: test_unfoldr;
- "test_hashtbl" >:: test_hashtbl;
- "test_int_range" >:: test_int_range;
- "test_take" >:: test_take;
- "test_regression1" >:: test_regression1;
- ]
diff --git a/setup.ml b/setup.ml
index 883fd52e..74763e94 100644
--- a/setup.ml
+++ b/setup.ml
@@ -1,7 +1,7 @@
(* setup.ml generated for the first time by OASIS v0.4.4 *)
(* OASIS_START *)
-(* DO NOT EDIT (digest: 4828f89967677c4737a4a949042a8d4c) *)
+(* DO NOT EDIT (digest: 43c616e040b0bb8b601c67da9e06ec15) *)
(*
Regenerated by OASIS v0.4.5
Visit http://oasis.forge.ocamlcore.org for more information and
@@ -6819,31 +6819,11 @@ let setup_t =
("containers",
OCamlbuildDocPlugin.doc_build
{
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_misc",
- OCamlbuildDocPlugin.doc_build
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_string",
- OCamlbuildDocPlugin.doc_build
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_advanced",
- OCamlbuildDocPlugin.doc_build
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_lwt",
- OCamlbuildDocPlugin.doc_build
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
+ OCamlbuildDocPlugin.extra_args =
+ [
+ "-use-ocamlfind";
+ "-docflags '-colorize-code -short-functors -charset utf-8'"
+ ];
run_path = "."
})
];
@@ -6866,31 +6846,11 @@ let setup_t =
("containers",
OCamlbuildDocPlugin.doc_clean
{
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_misc",
- OCamlbuildDocPlugin.doc_clean
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_string",
- OCamlbuildDocPlugin.doc_clean
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_advanced",
- OCamlbuildDocPlugin.doc_clean
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
- run_path = "."
- });
- ("containers_lwt",
- OCamlbuildDocPlugin.doc_clean
- {
- OCamlbuildDocPlugin.extra_args = ["-use-ocamlfind"];
+ OCamlbuildDocPlugin.extra_args =
+ [
+ "-use-ocamlfind";
+ "-docflags '-colorize-code -short-functors -charset utf-8'"
+ ];
run_path = "."
})
];
@@ -6912,10 +6872,10 @@ let setup_t =
oasis_version = "0.4";
ocaml_version = Some (OASISVersion.VGreaterEqual "4.00.1");
findlib_version = None;
- alpha_features = [];
+ alpha_features = ["ocamlbuild_more_args"];
beta_features = [];
name = "containers";
- version = "0.6.1";
+ version = "0.7";
license =
OASISLicense.DEP5License
(OASISLicense.DEP5Unit
@@ -6986,18 +6946,6 @@ let setup_t =
"Build the misc library, containing everything from the rotating kitchen sink to automatic banana distributors";
flag_default = [(OASISExpr.EBool true, false)]
});
- Flag
- ({
- cs_name = "cgi";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- flag_description =
- Some
- "Build modules related to FastCGI, depending on CamlGI";
- flag_default = [(OASISExpr.EBool true, false)]
- });
Flag
({
cs_name = "lwt";
@@ -7030,6 +6978,17 @@ let setup_t =
flag_description = Some "Build and run benchmarks";
flag_default = [(OASISExpr.EBool true, false)]
});
+ Flag
+ ({
+ cs_name = "bigarray";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ flag_description =
+ Some "Build modules that depend on bigarrays";
+ flag_default = [(OASISExpr.EBool true, false)]
+ });
Library
({
cs_name = "containers";
@@ -7039,7 +6998,7 @@ let setup_t =
{
bs_build = [(OASISExpr.EBool true, true)];
bs_install = [(OASISExpr.EBool true, true)];
- bs_path = "core";
+ bs_path = "src/core";
bs_compiled_object = Best;
bs_build_depends = [FindlibPackage ("bytes", None)];
bs_build_tools = [ExternalTool "ocamlbuild"];
@@ -7056,16 +7015,7 @@ let setup_t =
lib_modules =
[
"CCVector";
- "CCDeque";
- "CCGen";
- "Gen_intf";
- "CCSequence";
- "CCFQueue";
- "CCMultiMap";
- "CCMultiSet";
- "CCBV";
"CCPrint";
- "CCPersistentHashtbl";
"CCError";
"CCHeap";
"CCList";
@@ -7073,22 +7023,15 @@ let setup_t =
"CCPair";
"CCFun";
"CCHash";
- "CCKList";
"CCInt";
"CCBool";
"CCFloat";
"CCArray";
"CCOrd";
- "CCIO";
"CCRandom";
- "CCKTree";
- "CCTrie";
"CCString";
"CCHashtbl";
- "CCFlatHashtbl";
- "CCSexp";
- "CCMap";
- "CCCache"
+ "CCMap"
];
lib_pack = false;
lib_internal_modules = [];
@@ -7096,6 +7039,138 @@ let setup_t =
lib_findlib_name = None;
lib_findlib_containers = []
});
+ Library
+ ({
+ cs_name = "containers_io";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ bs_build = [(OASISExpr.EBool true, true)];
+ bs_install = [(OASISExpr.EBool true, true)];
+ bs_path = "src/io";
+ bs_compiled_object = Best;
+ bs_build_depends = [FindlibPackage ("bytes", None)];
+ bs_build_tools = [ExternalTool "ocamlbuild"];
+ bs_c_sources = [];
+ bs_data_files = [];
+ bs_ccopt = [(OASISExpr.EBool true, [])];
+ bs_cclib = [(OASISExpr.EBool true, [])];
+ bs_dlllib = [(OASISExpr.EBool true, [])];
+ bs_dllpath = [(OASISExpr.EBool true, [])];
+ bs_byteopt = [(OASISExpr.EBool true, [])];
+ bs_nativeopt = [(OASISExpr.EBool true, [])]
+ },
+ {
+ lib_modules = ["CCIO"];
+ lib_pack = false;
+ lib_internal_modules = [];
+ lib_findlib_parent = Some "containers";
+ lib_findlib_name = Some "io";
+ lib_findlib_containers = []
+ });
+ Library
+ ({
+ cs_name = "containers_sexp";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ bs_build = [(OASISExpr.EBool true, true)];
+ bs_install = [(OASISExpr.EBool true, true)];
+ bs_path = "src/sexp";
+ bs_compiled_object = Best;
+ bs_build_depends = [FindlibPackage ("bytes", None)];
+ bs_build_tools = [ExternalTool "ocamlbuild"];
+ bs_c_sources = [];
+ bs_data_files = [];
+ bs_ccopt = [(OASISExpr.EBool true, [])];
+ bs_cclib = [(OASISExpr.EBool true, [])];
+ bs_dlllib = [(OASISExpr.EBool true, [])];
+ bs_dllpath = [(OASISExpr.EBool true, [])];
+ bs_byteopt = [(OASISExpr.EBool true, [])];
+ bs_nativeopt = [(OASISExpr.EBool true, [])]
+ },
+ {
+ lib_modules = ["CCSexp"; "CCSexpStream"; "CCSexpM"];
+ lib_pack = false;
+ lib_internal_modules = [];
+ lib_findlib_parent = Some "containers";
+ lib_findlib_name = Some "sexp";
+ lib_findlib_containers = []
+ });
+ Library
+ ({
+ cs_name = "containers_data";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ bs_build = [(OASISExpr.EBool true, true)];
+ bs_install = [(OASISExpr.EBool true, true)];
+ bs_path = "src/data";
+ bs_compiled_object = Best;
+ bs_build_depends = [];
+ bs_build_tools = [ExternalTool "ocamlbuild"];
+ bs_c_sources = [];
+ bs_data_files = [];
+ bs_ccopt = [(OASISExpr.EBool true, [])];
+ bs_cclib = [(OASISExpr.EBool true, [])];
+ bs_dlllib = [(OASISExpr.EBool true, [])];
+ bs_dllpath = [(OASISExpr.EBool true, [])];
+ bs_byteopt = [(OASISExpr.EBool true, [])];
+ bs_nativeopt = [(OASISExpr.EBool true, [])]
+ },
+ {
+ lib_modules =
+ [
+ "CCMultiMap";
+ "CCMultiSet";
+ "CCTrie";
+ "CCFlatHashtbl";
+ "CCCache";
+ "CCPersistentHashtbl";
+ "CCDeque";
+ "CCFQueue";
+ "CCBV";
+ "CCMixtbl"
+ ];
+ lib_pack = false;
+ lib_internal_modules = [];
+ lib_findlib_parent = Some "containers";
+ lib_findlib_name = Some "data";
+ lib_findlib_containers = []
+ });
+ Library
+ ({
+ cs_name = "containers_iter";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ bs_build = [(OASISExpr.EBool true, true)];
+ bs_install = [(OASISExpr.EBool true, true)];
+ bs_path = "src/iter";
+ bs_compiled_object = Best;
+ bs_build_depends = [];
+ bs_build_tools = [ExternalTool "ocamlbuild"];
+ bs_c_sources = [];
+ bs_data_files = [];
+ bs_ccopt = [(OASISExpr.EBool true, [])];
+ bs_cclib = [(OASISExpr.EBool true, [])];
+ bs_dlllib = [(OASISExpr.EBool true, [])];
+ bs_dllpath = [(OASISExpr.EBool true, [])];
+ bs_byteopt = [(OASISExpr.EBool true, [])];
+ bs_nativeopt = [(OASISExpr.EBool true, [])]
+ },
+ {
+ lib_modules = ["CCKTree"; "CCKList"];
+ lib_pack = false;
+ lib_internal_modules = [];
+ lib_findlib_parent = Some "containers";
+ lib_findlib_name = Some "iter";
+ lib_findlib_containers = []
+ });
Library
({
cs_name = "containers_string";
@@ -7105,7 +7180,7 @@ let setup_t =
{
bs_build = [(OASISExpr.EBool true, true)];
bs_install = [(OASISExpr.EBool true, true)];
- bs_path = "string";
+ bs_path = "src/string";
bs_compiled_object = Best;
bs_build_depends = [];
bs_build_tools = [ExternalTool "ocamlbuild"];
@@ -7135,9 +7210,13 @@ let setup_t =
{
bs_build = [(OASISExpr.EBool true, true)];
bs_install = [(OASISExpr.EBool true, true)];
- bs_path = "advanced";
+ bs_path = "src/advanced";
bs_compiled_object = Best;
- bs_build_depends = [InternalLibrary "containers"];
+ bs_build_depends =
+ [
+ InternalLibrary "containers";
+ FindlibPackage ("sequence", None)
+ ];
bs_build_tools = [ExternalTool "ocamlbuild"];
bs_c_sources = [];
bs_data_files = [];
@@ -7157,6 +7236,41 @@ let setup_t =
lib_findlib_name = Some "advanced";
lib_findlib_containers = []
});
+ Library
+ ({
+ cs_name = "containers_bigarray";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ bs_build = [(OASISExpr.EBool true, true)];
+ bs_install = [(OASISExpr.EBool true, true)];
+ bs_path = "src/bigarray";
+ bs_compiled_object = Best;
+ bs_build_depends =
+ [
+ InternalLibrary "containers";
+ FindlibPackage ("bigarray", None);
+ FindlibPackage ("bytes", None)
+ ];
+ bs_build_tools = [ExternalTool "ocamlbuild"];
+ bs_c_sources = [];
+ bs_data_files = [];
+ bs_ccopt = [(OASISExpr.EBool true, [])];
+ bs_cclib = [(OASISExpr.EBool true, [])];
+ bs_dlllib = [(OASISExpr.EBool true, [])];
+ bs_dllpath = [(OASISExpr.EBool true, [])];
+ bs_byteopt = [(OASISExpr.EBool true, [])];
+ bs_nativeopt = [(OASISExpr.EBool true, [])]
+ },
+ {
+ lib_modules = ["CCBigstring"];
+ lib_pack = false;
+ lib_internal_modules = [];
+ lib_findlib_parent = Some "containers";
+ lib_findlib_name = Some "bigarray";
+ lib_findlib_containers = []
+ });
Library
({
cs_name = "containers_pervasives";
@@ -7166,7 +7280,7 @@ let setup_t =
{
bs_build = [(OASISExpr.EBool true, true)];
bs_install = [(OASISExpr.EBool true, true)];
- bs_path = "pervasives";
+ bs_path = "src/pervasives";
bs_compiled_object = Best;
bs_build_depends = [InternalLibrary "containers"];
bs_build_tools = [ExternalTool "ocamlbuild"];
@@ -7196,12 +7310,12 @@ let setup_t =
{
bs_build = [(OASISExpr.EBool true, true)];
bs_install = [(OASISExpr.EBool true, true)];
- bs_path = "misc";
+ bs_path = "src/misc";
bs_compiled_object = Best;
bs_build_depends =
[
- FindlibPackage ("unix", None);
- InternalLibrary "containers"
+ InternalLibrary "containers";
+ InternalLibrary "containers_data"
];
bs_build_tools = [ExternalTool "ocamlbuild"];
bs_c_sources = [];
@@ -7245,8 +7359,7 @@ let setup_t =
"Ty";
"Cause";
"AVL";
- "ParseReact";
- "Mixtbl"
+ "ParseReact"
];
lib_pack = true;
lib_internal_modules = [];
@@ -7271,7 +7384,7 @@ let setup_t =
(OASISExpr.EBool true, false);
(OASISExpr.EFlag "thread", true)
];
- bs_path = "threads/";
+ bs_path = "src/threads/";
bs_compiled_object = Best;
bs_build_depends =
[
@@ -7317,13 +7430,12 @@ let setup_t =
(OASISExpr.EFlag "lwt", OASISExpr.EFlag "misc"),
true)
];
- bs_path = "lwt";
+ bs_path = "src/lwt";
bs_compiled_object = Best;
bs_build_depends =
[
InternalLibrary "containers";
FindlibPackage ("lwt", None);
- FindlibPackage ("lwt.unix", None);
InternalLibrary "containers_misc"
];
bs_build_tools = [ExternalTool "ocamlbuild"];
@@ -7337,55 +7449,13 @@ let setup_t =
bs_nativeopt = [(OASISExpr.EBool true, [])]
},
{
- lib_modules = ["Behavior"; "Lwt_automaton"; "Lwt_actor"];
+ lib_modules = ["Lwt_automaton"; "Lwt_actor"];
lib_pack = true;
lib_internal_modules = [];
lib_findlib_parent = Some "containers";
lib_findlib_name = Some "lwt";
lib_findlib_containers = []
});
- Library
- ({
- cs_name = "containers_cgi";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EFlag "cgi", true)
- ];
- bs_install =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EFlag "cgi", true)
- ];
- bs_path = "cgi";
- bs_compiled_object = Best;
- bs_build_depends =
- [
- InternalLibrary "containers";
- FindlibPackage ("CamlGI", None)
- ];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {
- lib_modules = ["ToWeb"];
- lib_pack = false;
- lib_internal_modules = [];
- lib_findlib_parent = Some "containers";
- lib_findlib_name = Some "cgi";
- lib_findlib_containers = []
- });
Doc
({
cs_name = "containers";
@@ -7414,118 +7484,6 @@ let setup_t =
doc_build_tools =
[ExternalTool "ocamlbuild"; ExternalTool "ocamldoc"]
});
- Doc
- ({
- cs_name = "containers_misc";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- doc_type = (`Doc, "ocamlbuild", Some "0.3");
- doc_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- doc_build =
- [
- (OASISExpr.ENot (OASISExpr.EFlag "docs"), false);
- (OASISExpr.EFlag "docs", true)
- ];
- doc_install = [(OASISExpr.EBool true, true)];
- doc_install_dir = "$docdir";
- doc_title = "Containers_misc docs";
- doc_authors = [];
- doc_abstract = None;
- doc_format = OtherDoc;
- doc_data_files = [];
- doc_build_tools =
- [ExternalTool "ocamlbuild"; ExternalTool "ocamldoc"]
- });
- Doc
- ({
- cs_name = "containers_string";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- doc_type = (`Doc, "ocamlbuild", Some "0.3");
- doc_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- doc_build =
- [
- (OASISExpr.ENot (OASISExpr.EFlag "docs"), false);
- (OASISExpr.EFlag "docs", true)
- ];
- doc_install = [(OASISExpr.EBool true, true)];
- doc_install_dir = "$docdir";
- doc_title = "Containers_string docs";
- doc_authors = [];
- doc_abstract = None;
- doc_format = OtherDoc;
- doc_data_files = [];
- doc_build_tools =
- [ExternalTool "ocamlbuild"; ExternalTool "ocamldoc"]
- });
- Doc
- ({
- cs_name = "containers_advanced";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- doc_type = (`Doc, "ocamlbuild", Some "0.3");
- doc_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- doc_build =
- [
- (OASISExpr.ENot (OASISExpr.EFlag "docs"), false);
- (OASISExpr.EFlag "docs", true)
- ];
- doc_install = [(OASISExpr.EBool true, true)];
- doc_install_dir = "$docdir";
- doc_title = "Containers_advanced docs";
- doc_authors = [];
- doc_abstract = None;
- doc_format = OtherDoc;
- doc_data_files = [];
- doc_build_tools =
- [ExternalTool "ocamlbuild"; ExternalTool "ocamldoc"]
- });
- Doc
- ({
- cs_name = "containers_lwt";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- doc_type = (`Doc, "ocamlbuild", Some "0.3");
- doc_custom =
- {
- pre_command = [(OASISExpr.EBool true, None)];
- post_command = [(OASISExpr.EBool true, None)]
- };
- doc_build =
- [
- (OASISExpr.ENot (OASISExpr.EFlag "docs"), false);
- (OASISExpr.EFlag "docs", true)
- ];
- doc_install = [(OASISExpr.EBool true, true)];
- doc_install_dir = "$docdir";
- doc_title = "Containers_lwt docs";
- doc_authors = [];
- doc_abstract = None;
- doc_format = OtherDoc;
- doc_data_files = [];
- doc_build_tools =
- [ExternalTool "ocamlbuild"; ExternalTool "ocamldoc"]
- });
Executable
({
cs_name = "run_benchs";
@@ -7549,7 +7507,11 @@ let setup_t =
InternalLibrary "containers";
InternalLibrary "containers_misc";
InternalLibrary "containers_advanced";
+ InternalLibrary "containers_data";
InternalLibrary "containers_string";
+ InternalLibrary "containers_iter";
+ FindlibPackage ("sequence", None);
+ FindlibPackage ("gen", None);
FindlibPackage ("benchmark", None)
];
bs_build_tools = [ExternalTool "ocamlbuild"];
@@ -7615,7 +7577,8 @@ let setup_t =
bs_build_depends =
[
InternalLibrary "containers";
- FindlibPackage ("benchmark", None)
+ FindlibPackage ("benchmark", None);
+ FindlibPackage ("gen", None)
];
bs_build_tools = [ExternalTool "ocamlbuild"];
bs_c_sources = [];
@@ -7661,43 +7624,6 @@ let setup_t =
},
{exec_custom = false; exec_main_is = "test_levenshtein.ml"
});
- Executable
- ({
- cs_name = "test_lwt";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EAnd
- (OASISExpr.EFlag "tests",
- OASISExpr.EFlag "lwt"),
- true)
- ];
- bs_install = [(OASISExpr.EBool true, false)];
- bs_path = "tests/lwt/";
- bs_compiled_object = Best;
- bs_build_depends =
- [
- InternalLibrary "containers";
- FindlibPackage ("lwt", None);
- FindlibPackage ("lwt.unix", None);
- FindlibPackage ("oUnit", None);
- InternalLibrary "containers_lwt"
- ];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {exec_custom = false; exec_main_is = "test_Behavior.ml"});
Executable
({
cs_name = "test_threads";
@@ -7754,6 +7680,13 @@ let setup_t =
InternalLibrary "containers";
InternalLibrary "containers_misc";
InternalLibrary "containers_string";
+ InternalLibrary "containers_iter";
+ InternalLibrary "containers_io";
+ InternalLibrary "containers_advanced";
+ InternalLibrary "containers_sexp";
+ InternalLibrary "containers_bigarray";
+ FindlibPackage ("sequence", None);
+ FindlibPackage ("gen", None);
FindlibPackage ("oUnit", None);
FindlibPackage ("QTest2Lib", None)
];
@@ -7789,7 +7722,10 @@ let setup_t =
bs_build_depends =
[
InternalLibrary "containers";
+ InternalLibrary "containers_data";
FindlibPackage ("oUnit", None);
+ FindlibPackage ("sequence", None);
+ FindlibPackage ("gen", None);
FindlibPackage ("qcheck", None);
InternalLibrary "containers_misc"
];
@@ -7838,39 +7774,6 @@ let setup_t =
InternalExecutable "run_qtest"
]
});
- Executable
- ({
- cs_name = "web_pwd";
- cs_data = PropList.Data.create ();
- cs_plugin_data = []
- },
- {
- bs_build =
- [
- (OASISExpr.EBool true, false);
- (OASISExpr.EFlag "cgi", true)
- ];
- bs_install = [(OASISExpr.EBool true, false)];
- bs_path = "examples/cgi/";
- bs_compiled_object = Byte;
- bs_build_depends =
- [
- InternalLibrary "containers";
- InternalLibrary "containers_cgi";
- FindlibPackage ("threads", None);
- FindlibPackage ("CamlGI", None)
- ];
- bs_build_tools = [ExternalTool "ocamlbuild"];
- bs_c_sources = [];
- bs_data_files = [];
- bs_ccopt = [(OASISExpr.EBool true, [])];
- bs_cclib = [(OASISExpr.EBool true, [])];
- bs_dlllib = [(OASISExpr.EBool true, [])];
- bs_dllpath = [(OASISExpr.EBool true, [])];
- bs_byteopt = [(OASISExpr.EBool true, [])];
- bs_nativeopt = [(OASISExpr.EBool true, [])]
- },
- {exec_custom = false; exec_main_is = "web_pwd.ml"});
Executable
({
cs_name = "lambda";
@@ -7917,7 +7820,7 @@ let setup_t =
bs_install = [(OASISExpr.EBool true, false)];
bs_path = "examples/";
bs_compiled_object = Native;
- bs_build_depends = [InternalLibrary "containers"];
+ bs_build_depends = [InternalLibrary "containers_sexp"];
bs_build_tools = [ExternalTool "ocamlbuild"];
bs_c_sources = [];
bs_data_files = [];
@@ -7929,6 +7832,33 @@ let setup_t =
bs_nativeopt = [(OASISExpr.EBool true, [])]
},
{exec_custom = false; exec_main_is = "id_sexp.ml"});
+ Executable
+ ({
+ cs_name = "id_sexp2";
+ cs_data = PropList.Data.create ();
+ cs_plugin_data = []
+ },
+ {
+ bs_build =
+ [
+ (OASISExpr.EBool true, false);
+ (OASISExpr.EFlag "misc", true)
+ ];
+ bs_install = [(OASISExpr.EBool true, false)];
+ bs_path = "examples/";
+ bs_compiled_object = Native;
+ bs_build_depends = [InternalLibrary "containers_sexp"];
+ bs_build_tools = [ExternalTool "ocamlbuild"];
+ bs_c_sources = [];
+ bs_data_files = [];
+ bs_ccopt = [(OASISExpr.EBool true, [])];
+ bs_cclib = [(OASISExpr.EBool true, [])];
+ bs_dlllib = [(OASISExpr.EBool true, [])];
+ bs_dllpath = [(OASISExpr.EBool true, [])];
+ bs_byteopt = [(OASISExpr.EBool true, [])];
+ bs_nativeopt = [(OASISExpr.EBool true, [])]
+ },
+ {exec_custom = false; exec_main_is = "id_sexp2.ml"});
SrcRepo
({
cs_name = "head";
@@ -7956,7 +7886,8 @@ let setup_t =
};
oasis_fn = Some "_oasis";
oasis_version = "0.4.5";
- oasis_digest = Some "\224Im\201\235\195\005\221\244\022\209\165\168XI>";
+ oasis_digest =
+ Some "\031\146\017A\213\149\236\192\252\238\156-\202*`\143";
oasis_exec = None;
oasis_setup_args = [];
setup_update = false
@@ -7964,6 +7895,6 @@ let setup_t =
let setup () = BaseSetup.setup setup_t;;
-# 7968 "setup.ml"
+# 7899 "setup.ml"
(* OASIS_STOP *)
let () = setup ();;
diff --git a/advanced/CCBatch.ml b/src/advanced/CCBatch.ml
similarity index 100%
rename from advanced/CCBatch.ml
rename to src/advanced/CCBatch.ml
diff --git a/advanced/CCBatch.mli b/src/advanced/CCBatch.mli
similarity index 100%
rename from advanced/CCBatch.mli
rename to src/advanced/CCBatch.mli
diff --git a/advanced/CCCat.ml b/src/advanced/CCCat.ml
similarity index 100%
rename from advanced/CCCat.ml
rename to src/advanced/CCCat.ml
diff --git a/advanced/CCCat.mli b/src/advanced/CCCat.mli
similarity index 100%
rename from advanced/CCCat.mli
rename to src/advanced/CCCat.mli
diff --git a/advanced/CCLinq.ml b/src/advanced/CCLinq.ml
similarity index 90%
rename from advanced/CCLinq.ml
rename to src/advanced/CCLinq.ml
index 17cf74de..fd2e79a1 100644
--- a/advanced/CCLinq.ml
+++ b/src/advanced/CCLinq.ml
@@ -38,12 +38,12 @@ let _id x = x
exception ExitWithError of string
let _exit_with_error s = raise (ExitWithError s)
-let _error_of_exn f = try `Ok (f ()) with ExitWithError s -> `Error
+let _error_of_exn f = try `Ok (f ()) with ExitWithError s -> `Error s
type 'a collection =
| Seq : 'a sequence -> 'a collection
| List : 'a list -> 'a collection
- | Set : (module CCSequence.Set.S
+ | Set : (module Sequence.Set.S
with type elt = 'a and type t = 'b) * 'b -> 'a collection
module PMap = struct
@@ -103,7 +103,7 @@ module PMap = struct
}
let make_cmp (type key) ?(cmp=Pervasives.compare) () =
- let module M = CCSequence.Map.Make(struct
+ let module M = Sequence.Map.Make(struct
type t = key
let compare = cmp
end) in
@@ -167,26 +167,26 @@ module PMap = struct
| None -> None
| Some v -> Some (f v)
);
- to_seq = CCSequence.map (fun (x,y) -> x, f y) m.to_seq;
+ to_seq = Sequence.map (fun (x,y) -> x, f y) m.to_seq;
fold = (fun f' acc ->
m.fold (fun acc x y -> f' acc x (f y)) acc
);
}
- let to_list m = CCSequence.to_rev_list m.to_seq
+ let to_list m = Sequence.to_rev_list m.to_seq
let to_coll m = Seq m.to_seq
let reverse ~build m =
let build = make ~build () in
- let seq = CCSequence.map (fun (x,y) -> y,x) (to_seq m) in
+ let seq = Sequence.map (fun (x,y) -> y,x) (to_seq m) in
multimap_of_seq ~build seq
let reverse_multimap ~build m =
let build = make ~build () in
let seq = to_seq m in
- let seq = CCSequence.flat_map
- (fun (x,l) -> CCSequence.map (fun y -> y,x) (CCSequence.of_list l)
+ let seq = Sequence.flat_map
+ (fun (x,l) -> Sequence.map (fun y -> y,x) (Sequence.of_list l)
) seq
in
multimap_of_seq ~build seq
@@ -211,10 +211,10 @@ type ('a,'b) group_join_descr = {
module Coll = struct
let of_seq s = Seq s
let of_list l = List l
- let of_array a = Seq (CCSequence.of_array a)
+ let of_array a = Seq (Sequence.of_array a)
let set_of_seq (type elt) ?(cmp=Pervasives.compare) seq =
- let module S = CCSequence.Set.Make(struct
+ let module S = Sequence.Set.Make(struct
type t = elt
let compare = cmp
end) in
@@ -225,15 +225,15 @@ module Coll = struct
| Seq s -> s
| List l -> (fun k -> List.iter k l)
| Set (m, set) ->
- let module S = (val m : CCSequence.Set.S
+ let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in
S.to_seq set
let to_list (type elt) = function
- | Seq s -> CCSequence.to_list s
+ | Seq s -> Sequence.to_list s
| List l -> l
| Set (m, set) ->
- let module S = (val m : CCSequence.Set.S
+ let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in
S.elements set
@@ -245,30 +245,30 @@ module Coll = struct
let fold (type elt) f acc c = match c with
| List l -> List.fold_left f acc l
- | Seq s -> CCSequence.fold f acc s
+ | Seq s -> Sequence.fold f acc s
| Set (m, set) ->
- let module S = (val m : CCSequence.Set.S
+ let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in
S.fold (fun x acc -> f acc x) set acc
let map f c =
- _fmap ~lst:(List.map f) ~seq:(CCSequence.map f) c
+ _fmap ~lst:(List.map f) ~seq:(Sequence.map f) c
let filter p c =
- _fmap ~lst:(List.filter p) ~seq:(CCSequence.filter p) c
+ _fmap ~lst:(List.filter p) ~seq:(Sequence.filter p) c
let flat_map f c =
let c' = to_seq c in
- Seq (CCSequence.flatMap (fun x -> to_seq (f x)) c')
+ Seq (Sequence.flatMap (fun x -> to_seq (f x)) c')
let filter_map f c =
- _fmap ~lst:(CCList.filter_map f) ~seq:(CCSequence.fmap f) c
+ _fmap ~lst:(CCList.filter_map f) ~seq:(Sequence.fmap f) c
let size (type elt) = function
| List l -> List.length l
- | Seq s -> CCSequence.length s
+ | Seq s -> Sequence.length s
| Set (m, set) ->
- let module S = (val m : CCSequence.Set.S
+ let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in
S.cardinal set
@@ -278,12 +278,12 @@ module Coll = struct
| List [] -> fail ()
| List (x::_) -> x
| Seq s ->
- begin match CCSequence.to_list (CCSequence.take 1 s) with
+ begin match Sequence.to_list (Sequence.take 1 s) with
| [x] -> x
| _ -> fail ()
end
| Set (m, set) ->
- let module S = (val m : CCSequence.Set.S
+ let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in
try S.choose set with Not_found -> fail ()
@@ -292,7 +292,7 @@ module Coll = struct
with ExitWithError s -> `Error s
let take n c =
- _fmap ~lst:(CCList.take n) ~seq:(CCSequence.take n) c
+ _fmap ~lst:(CCList.take n) ~seq:(Sequence.take n) c
exception MySurpriseExit
@@ -308,7 +308,7 @@ module Coll = struct
let sort cmp c = match c with
| List l -> List (List.sort cmp l)
- | Seq s -> List (List.sort cmp (CCSequence.to_rev_list s))
+ | Seq s -> List (List.sort cmp (Sequence.to_rev_list s))
| _ -> set_of_seq ~cmp (to_seq c)
let search obj c =
@@ -328,9 +328,9 @@ module Coll = struct
let contains (type elt) ~eq x c = match c with
| List l -> List.exists (eq x) l
- | Seq s -> CCSequence.exists (eq x) s
+ | Seq s -> Sequence.exists (eq x) s
| Set (m, set) ->
- let module S = (val m : CCSequence.Set.S
+ let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in
(* XXX: here we don't use the equality relation *)
S.mem x set
@@ -338,10 +338,10 @@ module Coll = struct
let do_join ~join c1 c2 =
let build1 =
let seq = to_seq c1 in
- let seq = CCSequence.map (fun x -> join.join_key1 x, x) seq in
+ let seq = Sequence.map (fun x -> join.join_key1 x, x) seq in
PMap.multimap_of_seq ~build:(PMap.make ~build:join.join_build ()) seq
in
- let l = CCSequence.fold
+ let l = Sequence.fold
(fun acc y ->
let key = join.join_key2 y in
match PMap.get build1 key with
@@ -373,14 +373,14 @@ module Coll = struct
let do_product c1 c2 =
let s1 = to_seq c1 and s2 = to_seq c2 in
- of_seq (CCSequence.product s1 s2)
+ of_seq (Sequence.product s1 s2)
let do_union ~build c1 c2 =
let build = PMap.make ~build () in
to_seq c1 (fun x -> PMap.add build x ());
to_seq c2 (fun x -> PMap.add build x ());
let seq = PMap.to_seq (PMap.build_get build) in
- of_seq (CCSequence.map fst seq)
+ of_seq (Sequence.map fst seq)
type inter_status =
| InterLeft
@@ -408,7 +408,7 @@ module Coll = struct
let map = PMap.build_get build in
(* output elements of [c1] not in [map] *)
let seq = to_seq c1 in
- of_seq (CCSequence.filter (fun x -> not (PMap.mem map x)) seq)
+ of_seq (Sequence.filter (fun x -> not (PMap.mem map x)) seq)
end
(** {2 Query operators} *)
@@ -478,22 +478,22 @@ let of_array a =
Start (Coll.of_array a)
let of_array_i a =
- Start (Coll.of_seq (CCSequence.of_array_i a))
+ Start (Coll.of_seq (Sequence.of_array_i a))
let of_hashtbl h =
- Start (Coll.of_seq (CCSequence.of_hashtbl h))
+ Start (Coll.of_seq (Sequence.of_hashtbl h))
let of_seq seq =
Start (Coll.of_seq seq)
let of_queue q =
- Start (Coll.of_seq (CCSequence.of_queue q))
+ Start (Coll.of_seq (Sequence.of_queue q))
let of_stack s =
- Start (Coll.of_seq (CCSequence.of_stack s))
+ Start (Coll.of_seq (Sequence.of_stack s))
let of_string s =
- Start (Coll.of_seq (CCSequence.of_str s))
+ Start (Coll.of_seq (Sequence.of_str s))
(** {6 Execution} *)
@@ -519,9 +519,9 @@ and _optimize_unary : type a b. (a,b) unary -> a t -> b t
_optimize_unary
(FilterMap (fun x -> if p x then Some (f x) else None))
cont
- | PMap f, Binary (Append, q1, q2) ->
+ | PMap _, Binary (Append, q1, q2) ->
_optimize_binary Append (Unary (u, q1)) (Unary (u, q2))
- | Filter p, Binary (Append, q1, q2) ->
+ | Filter _, Binary (Append, q1, q2) ->
_optimize_binary Append (Unary (u, q1)) (Unary (u, q2))
| Fold (f,acc), Unary (PMap f', cont) ->
_optimize_unary
@@ -553,7 +553,7 @@ let _do_unary : type a b. (a,b) unary -> a -> b
| Fold (f, acc) -> Coll.fold f acc c
| FoldMap (f, acc) -> PMap.fold f acc c
| Reduce (safety, start, mix, stop) ->
- let acc = CCSequence.fold
+ let acc = Sequence.fold
(fun acc x -> match acc with
| None -> Some (start x)
| Some acc -> Some (mix x acc)
@@ -578,7 +578,7 @@ let _do_unary : type a b. (a,b) unary -> a -> b
| Get (Implicit, k) -> PMap.get_exn c k
| Get (Explicit, k) -> PMap.get_err c k
| GroupBy (build,f) ->
- let seq = CCSequence.map (fun x -> f x, x) (Coll.to_seq c) in
+ let seq = Sequence.map (fun x -> f x, x) (Coll.to_seq c) in
PMap.multimap_of_seq ~build:(PMap.make ~build ()) seq
| Contains (eq, x) -> Coll.contains ~eq x c
| Count build ->
@@ -591,7 +591,7 @@ let _do_binary : type a b c. (a, b, c) binary -> a -> b -> c
| GroupJoin gjoin -> Coll.do_group_join ~gjoin c1 c2
| Product -> Coll.do_product c1 c2
| Append ->
- Coll.of_seq (CCSequence.append (Coll.to_seq c1) (Coll.to_seq c2))
+ Coll.of_seq (Sequence.append (Coll.to_seq c1) (Coll.to_seq c2))
| SetOp (Inter,build) -> Coll.do_inter ~build c1 c2
| SetOp (Union,build) -> Coll.do_union ~build c1 c2
| SetOp (Diff,build) -> Coll.do_diff ~build c1 c2
@@ -695,8 +695,8 @@ module M = struct
let flatten q =
let f m =
- let seq = CCSequence.flat_map
- (fun (k,v) -> CCSequence.map (fun v' -> k,v') (Coll.to_seq v))
+ let seq = Sequence.flat_map
+ (fun (k,v) -> Sequence.map (fun v' -> k,v') (Coll.to_seq v))
m.PMap.to_seq
in Coll.of_seq seq
in
@@ -704,8 +704,8 @@ module M = struct
let flatten' q =
let f m =
- let seq = CCSequence.flatMap
- (fun (k,v) -> CCSequence.map (fun v' -> k,v') (CCSequence.of_list v))
+ let seq = Sequence.flatMap
+ (fun (k,v) -> Sequence.map (fun v' -> k,v') (Sequence.of_list v))
m.PMap.to_seq
in Coll.of_seq seq
in
@@ -739,7 +739,7 @@ let group_by ?cmp ?eq ?hash f q =
Unary (GroupBy (_make_build ?cmp ?eq ?hash (),f), q)
let group_by' ?cmp ?eq ?hash f q =
- M.iter (group_by ?cmp f q)
+ M.iter (group_by ?cmp ?eq ?hash f q)
let count ?cmp ?eq ?hash () q =
Unary (Count (_make_build ?cmp ?eq ?hash ()), q)
@@ -885,16 +885,16 @@ let to_array q =
QueryMap ((fun c -> Array.of_list (Coll.to_list c)), q)
let to_seq q =
- QueryMap ((fun c -> CCSequence.persistent (Coll.to_seq c)), q)
+ QueryMap ((fun c -> Sequence.persistent (Coll.to_seq c)), q)
let to_hashtbl q =
- QueryMap ((fun c -> CCSequence.to_hashtbl (Coll.to_seq c)), q)
+ QueryMap ((fun c -> Sequence.to_hashtbl (Coll.to_seq c)), q)
let to_queue q =
- QueryMap ((fun c q -> CCSequence.to_queue q (Coll.to_seq c)), q)
+ QueryMap ((fun c q -> Sequence.to_queue q (Coll.to_seq c)), q)
let to_stack q =
- QueryMap ((fun c s -> CCSequence.to_stack s (Coll.to_seq c)), q)
+ QueryMap ((fun c s -> Sequence.to_stack s (Coll.to_seq c)), q)
module L = struct
let of_list l = Start (Coll.of_list l)
@@ -909,7 +909,7 @@ module AdaptSet(S : Set.S) = struct
return (Coll.of_seq (fun k -> S.iter k set))
let to_set q =
- let f c = CCSequence.fold (fun set x -> S.add x set) S.empty (Coll.to_seq c) in
+ let f c = Sequence.fold (fun set x -> S.add x set) S.empty (Coll.to_seq c) in
query_map f q
let run q = run (to_set q)
@@ -932,7 +932,7 @@ module AdaptMap(M : Map.S) = struct
let to_map q =
let f c =
- CCSequence.fold (fun m (x,y) -> M.add x y m) M.empty (Coll.to_seq c)
+ Sequence.fold (fun m (x,y) -> M.add x y m) M.empty (Coll.to_seq c)
in
query_map f q
@@ -1008,13 +1008,13 @@ module IO = struct
query_map f q
let lines' q =
- let f s = lazy (CCSequence.to_list (_lines s 0)) in
+ let f s = lazy (Sequence.to_list (_lines s 0)) in
lazy_ (query_map f q)
let _join ~sep ?(stop="") l =
let buf = Buffer.create 128 in
let seq = Coll.to_seq l in
- CCSequence.iteri
+ Sequence.iteri
(fun i x ->
if i>0 then Buffer.add_string buf sep;
Buffer.add_string buf x)
@@ -1035,7 +1035,7 @@ module IO = struct
let out_lines oc q =
let x = run_exn q in
- CCSequence.iter (fun l -> output_string oc l; output_char oc '\n') (Coll.to_seq x)
+ Sequence.iter (fun l -> output_string oc l; output_char oc '\n') (Coll.to_seq x)
let to_file_exn filename q =
_with_file_out filename (fun oc -> out oc q)
diff --git a/advanced/CCLinq.mli b/src/advanced/CCLinq.mli
similarity index 100%
rename from advanced/CCLinq.mli
rename to src/advanced/CCLinq.mli
diff --git a/advanced/CCMonadIO.ml b/src/advanced/CCMonadIO.ml
similarity index 100%
rename from advanced/CCMonadIO.ml
rename to src/advanced/CCMonadIO.ml
diff --git a/advanced/CCMonadIO.mli b/src/advanced/CCMonadIO.mli
similarity index 100%
rename from advanced/CCMonadIO.mli
rename to src/advanced/CCMonadIO.mli
diff --git a/src/advanced/containers_advanced.mldylib b/src/advanced/containers_advanced.mldylib
new file mode 100644
index 00000000..0f1163e0
--- /dev/null
+++ b/src/advanced/containers_advanced.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 0f1ca0e2b031ae1710e26abf02cca256)
+Containers_advanced
+# OASIS_STOP
diff --git a/src/advanced/containers_advanced.mllib b/src/advanced/containers_advanced.mllib
new file mode 100644
index 00000000..0f1163e0
--- /dev/null
+++ b/src/advanced/containers_advanced.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 0f1ca0e2b031ae1710e26abf02cca256)
+Containers_advanced
+# OASIS_STOP
diff --git a/src/advanced/containers_advanced.mlpack b/src/advanced/containers_advanced.mlpack
new file mode 100644
index 00000000..7c96f38e
--- /dev/null
+++ b/src/advanced/containers_advanced.mlpack
@@ -0,0 +1,7 @@
+# OASIS_START
+# DO NOT EDIT (digest: 5a399cd532edb84596f3034081578694)
+CCLinq
+CCBatch
+CCCat
+CCMonadIO
+# OASIS_STOP
diff --git a/src/bigarray/CCBigstring.ml b/src/bigarray/CCBigstring.ml
new file mode 100644
index 00000000..efa37a74
--- /dev/null
+++ b/src/bigarray/CCBigstring.ml
@@ -0,0 +1,223 @@
+
+(*
+copyright (c) 2013-2014, simon cruanes
+all rights reserved.
+
+redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*)
+
+(** {1 Interface to 1-dimension Bigarrays of bytes (char)} *)
+
+module B = Bigarray.Array1
+
+type t = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
+
+let create size = B.create Bigarray.char Bigarray.c_layout size
+
+let empty = create 0
+
+let init size f =
+ let a = create size in
+ for i = 0 to size-1 do
+ B.unsafe_set a i (f i)
+ done;
+ a
+
+let fill = B.fill
+
+let get = B.get
+
+let set = B.set
+
+let size = B.dim
+
+let sub = B.sub
+
+let blit a i b j len =
+ let a' = sub a i len in
+ let b' = sub b j len in
+ B.blit a' b'
+
+let copy a =
+ let b = create (size a) in
+ B.blit a b;
+ b
+
+(*$T
+ copy (of_string "abcd") |> to_string = "abcd"
+ *)
+
+let fold f acc a =
+ let rec fold' f acc a i len =
+ if i = len then acc
+ else
+ let acc = f acc (get a i) in
+ fold' f acc a (i+1) len
+ in
+ fold' f acc a 0 (size a)
+
+let iter f a =
+ let n = size a in
+ for i = 0 to n-1 do
+ f (get a i)
+ done
+
+let rec equal_rec a b i len =
+ i = len
+ ||
+ ( get a i = get b i && equal_rec a b (i+1) len)
+
+let equal a b =
+ size a = size b
+ &&
+ equal_rec a b 0 (size a)
+
+(*$Q
+ Q.(pair printable_string printable_string) (fun (s1, s2) -> \
+ let a1 = of_string s1 and a2 = of_string s2 in \
+ equal a1 a2 = (s1 = s2))
+*)
+
+let rec compare_rec a b i len_a len_b =
+ if i=len_a && i=len_b then 0
+ else if i=len_a then -1
+ else if i=len_b then 1
+ else
+ match Char.compare (get a i) (get b i) with
+ | 0 -> compare_rec a b (i+1) len_a len_b
+ | n -> n
+
+let compare a b =
+ compare_rec a b 0 (size a) (size b)
+
+(*$T
+ compare (of_string "abc") (of_string "abd") < 0
+ compare (of_string "abc") (of_string "abcd") < 0
+ compare (of_string "abcd") (of_string "abc") > 0
+ compare (of_string "abc") (of_string "b") < 0
+*)
+
+(*$Q
+ Q.(pair string string) (fun (s1, s2) -> \
+ let a1 = of_string s1 and a2 = of_string s2 in \
+ CCInt.sign (compare a1 a2) = CCInt.sign (String.compare s1 s2))
+*)
+
+(** {2 Conversions} *)
+
+let to_bytes a =
+ Bytes.init (size a) (fun i -> B.unsafe_get a i)
+
+let of_bytes b =
+ init (Bytes.length b) (fun i -> Bytes.get b i)
+
+let of_bytes_slice b i len =
+ if i < 0 || i+len > Bytes.length b then invalid_arg "CCBigstring";
+ init len (fun j -> Bytes.get b (i+j))
+
+let sub_bytes a i len =
+ if i < 0 || i+len > size a then invalid_arg "CCBigstring";
+ Bytes.init len (fun j -> B.get a (i+j))
+
+let blit_to_bytes a i b j len =
+ if i < 0 || j < 0 || i+len > size a || j+len > Bytes.length b
+ then invalid_arg "CCBigstring";
+ for x=0 to len-1 do
+ Bytes.set b (j+x) (B.get a (i+x))
+ done
+
+let blit_of_bytes a i b j len =
+ if i < 0 || j < 0 || i+len > Bytes.length a || j+len > size b
+ then invalid_arg "CCBigstring";
+ for x=0 to len-1 do
+ B.set b (j+x) (Bytes.get a (i+x))
+ done
+
+let to_string a =
+ CCString.init (size a) (fun i -> B.unsafe_get a i)
+
+let of_string s =
+ init (String.length s) (fun i -> String.get s i)
+
+let of_string_slice s i len =
+ if i < 0 || i+len > String.length s then invalid_arg "CCBigstring";
+ init len (fun j -> String.get s (i+j))
+
+let sub_string a i len =
+ if i < 0 || i+len > size a then invalid_arg "CCBigstring";
+ CCString.init len (fun j -> B.get a (i+j))
+
+(*$T
+ of_string_slice "abcde" 1 3 |> to_string = "bcd"
+*)
+
+let blit_of_string a i b j len =
+ if i < 0 || j < 0 || i+len > String.length a || j+len > size b
+ then invalid_arg "CCBigstring";
+ for x=0 to len-1 do
+ B.set b (j+x) (String.get a (i+x))
+ done
+
+type 'a gen = unit -> 'a option
+type 'a sequence = ('a -> unit) -> unit
+
+let to_seq a k = iter k a
+
+let to_gen a =
+ let i = ref 0 in
+ let n = size a in
+ fun () ->
+ if !i = n then None
+ else (
+ let x = get a !i in
+ incr i;
+ Some x
+ )
+
+(*$T
+ of_string "abcd" |> to_gen |> Gen.to_string = "abcd"
+*)
+
+let to_seq_slice a i len =
+ to_seq (sub a i len)
+
+let to_gen_slice a i len =
+ to_gen (sub a i len)
+
+(** {2 Memory-map} *)
+
+let map_file_descr ?pos ?(shared=false) fd len =
+ B.map_file fd ?pos Bigarray.char Bigarray.c_layout shared len
+
+let with_map_file ?pos ?len ?(mode=0o644) ?(flags=[Open_rdonly]) ?shared name f =
+ let ic = open_in_gen flags mode name in
+ let len = match len with
+ | None -> in_channel_length ic
+ | Some n -> n
+ in
+ let a = map_file_descr ?pos ?shared (Unix.descr_of_in_channel ic) len in
+ try
+ let x = f a in
+ close_in ic;
+ x
+ with e ->
+ close_in ic;
+ raise e
diff --git a/src/bigarray/CCBigstring.mli b/src/bigarray/CCBigstring.mli
new file mode 100644
index 00000000..6f0582e1
--- /dev/null
+++ b/src/bigarray/CCBigstring.mli
@@ -0,0 +1,127 @@
+
+(*
+copyright (c) 2013-2014, simon cruanes
+all rights reserved.
+
+redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*)
+
+(** {1 Interface to 1-dimension Bigarrays of bytes (char)}
+
+@since 0.7 *)
+
+type t = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
+
+val create : int -> t
+(** Create a new bigstring of the given size. *)
+
+val empty : t
+(** Empty string *)
+
+val init : int -> (int -> char) -> t
+(** Initialize with the given function (called at every index) *)
+
+val fill : t -> char -> unit
+(** Fill with a single byte *)
+
+val size : t -> int
+(** Number of bytes *)
+
+val get : t -> int -> char
+
+val set : t -> int -> char -> unit
+
+val blit : t -> int -> t -> int -> int -> unit
+(** Blit a slice of the bigstring into another *)
+
+val copy : t -> t
+(** Copy of the string *)
+
+val sub : t -> int -> int -> t
+(** [sub s i len] takes a slice of length [len] from the string [s], starting
+ at offset [i].
+ @raise Invalid_argument if [i, len] doesn't designate a valid substring *)
+
+val fold : ('a -> char -> 'a) -> 'a -> t -> 'a
+
+val iter : (char -> unit) -> t -> unit
+
+val equal : t -> t -> bool
+
+val compare : t -> t -> int
+(** Lexicographic order *)
+
+(** {2 Conversions} *)
+
+val to_bytes : t -> Bytes.t
+
+val of_bytes : Bytes.t -> t
+
+val of_bytes_slice : Bytes.t -> int -> int -> t
+
+val sub_bytes : t -> int -> int -> Bytes.t
+
+val blit_to_bytes : t -> int -> Bytes.t -> int -> int -> unit
+
+val blit_of_bytes : Bytes.t -> int -> t -> int -> int -> unit
+
+val to_string : t -> string
+
+val of_string : string -> t
+
+val of_string_slice : string -> int -> int -> t
+
+val sub_string : t -> int -> int -> string
+
+val blit_of_string : string -> int -> t -> int -> int -> unit
+
+type 'a gen = unit -> 'a option
+type 'a sequence = ('a -> unit) -> unit
+
+val to_seq : t -> char sequence
+
+val to_gen : t -> char gen
+
+val to_seq_slice : t -> int -> int -> char sequence
+
+val to_gen_slice : t -> int -> int -> char gen
+
+(** {2 Memory-map} *)
+
+val with_map_file :
+ ?pos:int64 -> ?len:int -> ?mode:int -> ?flags:open_flag list -> ?shared:bool ->
+ string -> (t -> 'a) -> 'a
+(** [with_map_file name f] maps the file into memory, opening it, and
+ call [f] with a slice [pos.... pos+len] of the bytes of the file
+ where [len] is the length of the file if not provided.
+ When [f] returns, the file is closed.
+ @param pos offset in the file (default 0)
+ @param shared if true, modifications are shared between processes that
+ have mapped this file (requires the filedescr to be open in write mode).
+ @param mode the mode for the file, if it's created
+ @param flags opening flags (default rdonly)
+ see {!Bigarray.Array1.map_file} for more details *)
+
+val map_file_descr : ?pos:int64 -> ?shared:bool -> Unix.file_descr -> int -> t
+(** [map_file_descr descr len] is a lower-level access to an underlying file descriptor.
+ @param shared if true, modifications are shared between processes that
+ have mapped this file (requires the filedescr to be open in write mode).
+ see {!Bigarray.Array1.map_file} for more details *)
diff --git a/src/bigarray/containers_bigarray.mldylib b/src/bigarray/containers_bigarray.mldylib
new file mode 100644
index 00000000..10f13676
--- /dev/null
+++ b/src/bigarray/containers_bigarray.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 6398fca785a51b3ad28defb36820d456)
+CCBigstring
+# OASIS_STOP
diff --git a/src/bigarray/containers_bigarray.mllib b/src/bigarray/containers_bigarray.mllib
new file mode 100644
index 00000000..10f13676
--- /dev/null
+++ b/src/bigarray/containers_bigarray.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 6398fca785a51b3ad28defb36820d456)
+CCBigstring
+# OASIS_STOP
diff --git a/core/CCArray.ml b/src/core/CCArray.ml
similarity index 100%
rename from core/CCArray.ml
rename to src/core/CCArray.ml
diff --git a/core/CCArray.mli b/src/core/CCArray.mli
similarity index 100%
rename from core/CCArray.mli
rename to src/core/CCArray.mli
diff --git a/core/CCBool.ml b/src/core/CCBool.ml
similarity index 100%
rename from core/CCBool.ml
rename to src/core/CCBool.ml
diff --git a/core/CCBool.mli b/src/core/CCBool.mli
similarity index 100%
rename from core/CCBool.mli
rename to src/core/CCBool.mli
diff --git a/core/CCError.ml b/src/core/CCError.ml
similarity index 100%
rename from core/CCError.ml
rename to src/core/CCError.ml
diff --git a/core/CCError.mli b/src/core/CCError.mli
similarity index 100%
rename from core/CCError.mli
rename to src/core/CCError.mli
diff --git a/core/CCFloat.ml b/src/core/CCFloat.ml
similarity index 92%
rename from core/CCFloat.ml
rename to src/core/CCFloat.ml
index 6749913a..ad8ad32b 100644
--- a/core/CCFloat.ml
+++ b/src/core/CCFloat.ml
@@ -76,6 +76,17 @@ let sign (a:float) =
else if a > 0.0 then 1
else 0
+let fsign a =
+ if is_nan a then nan
+ else if a = 0. then a
+ else Pervasives.copysign 1. a
+
+exception TrapNaN of string
+
+let sign_exn (a:float) =
+ if is_nan a then raise (TrapNaN "sign")
+ else compare a 0.
+
let to_int (a:float) = Pervasives.int_of_float a
let of_int (a:int) = Pervasives.float_of_int a
diff --git a/core/CCFloat.mli b/src/core/CCFloat.mli
similarity index 82%
rename from core/CCFloat.mli
rename to src/core/CCFloat.mli
index 02da623e..bf1cd0f3 100644
--- a/core/CCFloat.mli
+++ b/src/core/CCFloat.mli
@@ -77,7 +77,20 @@ val random_small : t random_gen
val random_range : t -> t -> t random_gen
val sign : t -> int
-(** [sign t] is one of [-1, 0, 1] *)
+(** [sign t] is one of [-1, 0, 1], depending on how the float
+ compares to [0.]
+ @deprecated use {! fsign} or {!sign_exn} since it's more accurate *)
+
+val fsign : t -> float
+(** [fsign x] is one of [-1., -0., +0., +1.], or [nan] if [x] is NaN.
+ @since 0.7 *)
+
+exception TrapNaN of string
+val sign_exn : t -> int
+(** [sign_exn x] will return the sign of [x] as [1, 0] or [-1], or raise an
+ exception [TrapNaN] if [x] is a NaN.
+ Note that infinities have defined signs in OCaml.
+ @since 0.7 *)
val to_int : t -> int
val of_int : int -> t
diff --git a/core/CCFun.cppo.ml b/src/core/CCFun.cppo.ml
similarity index 100%
rename from core/CCFun.cppo.ml
rename to src/core/CCFun.cppo.ml
diff --git a/core/CCFun.mli b/src/core/CCFun.mli
similarity index 100%
rename from core/CCFun.mli
rename to src/core/CCFun.mli
diff --git a/core/CCHash.ml b/src/core/CCHash.ml
similarity index 100%
rename from core/CCHash.ml
rename to src/core/CCHash.ml
diff --git a/core/CCHash.mli b/src/core/CCHash.mli
similarity index 100%
rename from core/CCHash.mli
rename to src/core/CCHash.mli
diff --git a/core/CCHashtbl.ml b/src/core/CCHashtbl.ml
similarity index 93%
rename from core/CCHashtbl.ml
rename to src/core/CCHashtbl.ml
index 1a00239a..fe5289b7 100644
--- a/core/CCHashtbl.ml
+++ b/src/core/CCHashtbl.ml
@@ -40,6 +40,16 @@ let keys tbl k = Hashtbl.iter (fun key _ -> k key) tbl
let values tbl k = Hashtbl.iter (fun _ v -> k v) tbl
+let map_list f h =
+ Hashtbl.fold
+ (fun x y acc -> f x y :: acc)
+ h []
+
+(*$T
+ of_list [1,"a"; 2,"b"] |> map_list (fun x y -> string_of_int x ^ y) \
+ |> List.sort Pervasives.compare = ["1a"; "2b"]
+*)
+
let to_seq tbl k = Hashtbl.iter (fun key v -> k (key,v)) tbl
let of_seq seq =
@@ -71,6 +81,9 @@ module type S = sig
val values : 'a t -> 'a sequence
(** Iterate on values in the table *)
+ val map_list : (key -> 'a -> 'b) -> 'a t -> 'b list
+ (** Map on a hashtable's items, collect into a list *)
+
val to_seq : 'a t -> (key * 'a) sequence
(** Iterate on values in the table *)
@@ -95,6 +108,11 @@ module Make(X : Hashtbl.HashedType) = struct
let values tbl k = iter (fun _ v -> k v) tbl
+ let map_list f h =
+ fold
+ (fun x y acc -> f x y :: acc)
+ h []
+
let to_seq tbl k = iter (fun key v -> k (key,v)) tbl
let of_seq seq =
@@ -215,7 +233,7 @@ module MakeCounter(X : Hashtbl.HashedType) = struct
let n = get tbl x in
T.replace tbl x (n+1)
- let incr_by tbl n x =
+ let incr_by tbl n x =
let n' = get tbl x in
if n' + n <= 0
then T.remove tbl x
diff --git a/core/CCHashtbl.mli b/src/core/CCHashtbl.mli
similarity index 94%
rename from core/CCHashtbl.mli
rename to src/core/CCHashtbl.mli
index 5eb6acf1..abee28de 100644
--- a/core/CCHashtbl.mli
+++ b/src/core/CCHashtbl.mli
@@ -25,7 +25,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
-(** {1 Extension to the standard Hashtbl}
+(** {1 Extension to the standard Hashtbl}
@since 0.4 *)
@@ -44,6 +44,9 @@ val keys : ('a,'b) Hashtbl.t -> 'a sequence
val values : ('a,'b) Hashtbl.t -> 'b sequence
(** Iterate on values in the table *)
+val map_list : ('a -> 'b -> 'c) -> ('a, 'b) Hashtbl.t -> 'c list
+(** Map on a hashtable's items, collect into a list *)
+
val to_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence
(** Iterate on bindings in the table *)
@@ -70,6 +73,9 @@ module type S = sig
val values : 'a t -> 'a sequence
(** Iterate on values in the table *)
+ val map_list : (key -> 'a -> 'b) -> 'a t -> 'b list
+ (** Map on a hashtable's items, collect into a list *)
+
val to_seq : 'a t -> (key * 'a) sequence
(** Iterate on values in the table *)
diff --git a/core/CCHeap.ml b/src/core/CCHeap.ml
similarity index 100%
rename from core/CCHeap.ml
rename to src/core/CCHeap.ml
diff --git a/core/CCHeap.mli b/src/core/CCHeap.mli
similarity index 100%
rename from core/CCHeap.mli
rename to src/core/CCHeap.mli
diff --git a/core/CCInt.ml b/src/core/CCInt.ml
similarity index 100%
rename from core/CCInt.ml
rename to src/core/CCInt.ml
diff --git a/core/CCInt.mli b/src/core/CCInt.mli
similarity index 100%
rename from core/CCInt.mli
rename to src/core/CCInt.mli
diff --git a/core/CCList.ml b/src/core/CCList.ml
similarity index 100%
rename from core/CCList.ml
rename to src/core/CCList.ml
diff --git a/core/CCList.mli b/src/core/CCList.mli
similarity index 100%
rename from core/CCList.mli
rename to src/core/CCList.mli
diff --git a/core/CCMap.ml b/src/core/CCMap.ml
similarity index 100%
rename from core/CCMap.ml
rename to src/core/CCMap.ml
diff --git a/core/CCMap.mli b/src/core/CCMap.mli
similarity index 100%
rename from core/CCMap.mli
rename to src/core/CCMap.mli
diff --git a/core/CCOpt.ml b/src/core/CCOpt.ml
similarity index 100%
rename from core/CCOpt.ml
rename to src/core/CCOpt.ml
diff --git a/core/CCOpt.mli b/src/core/CCOpt.mli
similarity index 100%
rename from core/CCOpt.mli
rename to src/core/CCOpt.mli
diff --git a/core/CCOrd.ml b/src/core/CCOrd.ml
similarity index 100%
rename from core/CCOrd.ml
rename to src/core/CCOrd.ml
diff --git a/core/CCOrd.mli b/src/core/CCOrd.mli
similarity index 100%
rename from core/CCOrd.mli
rename to src/core/CCOrd.mli
diff --git a/core/CCPair.ml b/src/core/CCPair.ml
similarity index 100%
rename from core/CCPair.ml
rename to src/core/CCPair.ml
diff --git a/core/CCPair.mli b/src/core/CCPair.mli
similarity index 100%
rename from core/CCPair.mli
rename to src/core/CCPair.mli
diff --git a/core/CCPrint.ml b/src/core/CCPrint.ml
similarity index 100%
rename from core/CCPrint.ml
rename to src/core/CCPrint.ml
diff --git a/core/CCPrint.mli b/src/core/CCPrint.mli
similarity index 100%
rename from core/CCPrint.mli
rename to src/core/CCPrint.mli
diff --git a/core/CCRandom.ml b/src/core/CCRandom.ml
similarity index 100%
rename from core/CCRandom.ml
rename to src/core/CCRandom.ml
diff --git a/core/CCRandom.mli b/src/core/CCRandom.mli
similarity index 100%
rename from core/CCRandom.mli
rename to src/core/CCRandom.mli
diff --git a/core/CCString.cppo.ml b/src/core/CCString.cppo.ml
similarity index 91%
rename from core/CCString.cppo.ml
rename to src/core/CCString.cppo.ml
index 3948c8a2..097cd078 100644
--- a/core/CCString.cppo.ml
+++ b/src/core/CCString.cppo.ml
@@ -38,6 +38,8 @@ module type S = sig
val blit : t -> int -> t -> int -> int -> unit
(** See {!String.blit} *)
+ val fold : ('a -> char -> 'a) -> 'a -> t -> 'a
+
(** {2 Conversions} *)
val to_gen : t -> char gen
@@ -62,9 +64,8 @@ let init = String.init
#else
let init n f =
- let buf = Buffer.create n in
- for i = 0 to n-1 do Buffer.add_char buf (f i) done;
- Buffer.contents buf
+ let buf = Bytes.init n f in
+ Bytes.unsafe_to_string buf
#endif
@@ -182,10 +183,26 @@ let prefix ~pre s =
String.length pre <= String.length s &&
(let i = ref 0 in
while !i < String.length pre && s.[!i] = pre.[!i] do incr i done;
- !i = String.length pre)
+ !i = String.length pre
+ )
+
+let suffix ~suf s =
+ String.length suf <= String.length s &&
+ let off = String.length s - String.length suf in
+ (let i = ref 0 in
+ while !i < String.length suf && s.[off + !i] = suf.[!i] do incr i done;
+ !i = String.length suf
+ )
+
let blit = String.blit
+let fold f acc s =
+ let rec fold_rec f acc s i =
+ if i = String.length s then acc
+ else fold_rec f (f acc s.[i]) s (i+1)
+ in fold_rec f acc s 0
+
let _to_gen s i0 len =
let i = ref i0 in
fun () ->
@@ -277,6 +294,12 @@ module Sub = struct
if o1+len>len1 || o2+len>len2 then invalid_arg "CCString.Sub.blit";
String.blit a1 (i1+o1) a2 (i2+o2) len
+ let fold f acc (s,i,len) =
+ let rec fold_rec f acc s i j =
+ if i = j then acc
+ else fold_rec f (f acc s.[i]) s (i+1) j
+ in fold_rec f acc s i (i+len)
+
let to_gen (s,i,len) = _to_gen s i len
let to_seq (s,i,len) k =
for i=i to i+len-1 do k s.[i] done
diff --git a/core/CCString.mli b/src/core/CCString.mli
similarity index 80%
rename from core/CCString.mli
rename to src/core/CCString.mli
index 8945e525..807bb938 100644
--- a/core/CCString.mli
+++ b/src/core/CCString.mli
@@ -25,6 +25,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
(** {1 Basic String Utils}
+
Consider using {!Containers_string.KMP} for pattern search, or Regex
libraries. *)
@@ -42,6 +43,10 @@ module type S = sig
val blit : t -> int -> t -> int -> int -> unit
(** See {!String.blit} *)
+ val fold : ('a -> char -> 'a) -> 'a -> t -> 'a
+ (** Fold on chars by increasing index.
+ @since 0.7 *)
+
(** {2 Conversions} *)
val to_gen : t -> char gen
@@ -65,6 +70,11 @@ val init : int -> (int -> char) -> string
(** Analog to [Array.init].
@since 0.3.3 *)
+(*$T
+ init 3 (fun i -> [|'a'; 'b'; 'c'|].(i)) = "abc"
+ init 0 (fun _ -> assert false) = ""
+*)
+
val of_gen : char gen -> string
val of_seq : char sequence -> string
val of_klist : char klist -> string
@@ -74,19 +84,34 @@ val of_array : char array -> string
val to_array : string -> char array
val find : ?start:int -> sub:string -> string -> int
-(** Find [sub] in stringhe string, returns its first index or -1.
+(** Find [sub] in string, returns its first index or [-1].
Should only be used with very small [sub] *)
val is_sub : sub:string -> int -> string -> int -> len:int -> bool
-(** [is_sub ~sub i s j ~len] returns [true] iff stringhe substring of
- [sub] starting at position [i] and of length [len],
- is a substring of [s] starting at position [j] *)
+(** [is_sub ~sub i s j ~len] returns [true] iff the substring of
+ [sub] starting at position [i] and of length [len] *)
val repeat : string -> int -> string
-(** The same string, repeated n stringimes *)
+(** The same string, repeated n times *)
val prefix : pre:string -> string -> bool
-(** [str_prefix ~pre s] returns [true] iff [pre] is a prefix of [s] *)
+(** [prefix ~pre s] returns [true] iff [pre] is a prefix of [s] *)
+
+(*$T
+ prefix ~pre:"aab" "aabcd"
+ not (prefix ~pre:"ab" "aabcd")
+ not (prefix ~pre:"abcd" "abc")
+*)
+
+val suffix : suf:string -> string -> bool
+(** [suffix ~suf s] returns [true] iff [suf] is a suffix of [s]
+ @since 0.7 *)
+
+(*$T
+ suffix ~suf:"cd" "abcd"
+ not (suffix ~suf:"cd" "abcde")
+ not (suffix ~suf:"abcd" "cd")
+*)
include S with type t := string
@@ -148,4 +173,11 @@ module Sub : sig
(** Sub-slice *)
include S with type t := t
+
+ (*$T
+ let s = Sub.make "abcde" 1 3 in \
+ Sub.fold (fun acc x -> x::acc) [] s = ['d'; 'c'; 'b']
+ Sub.make "abcde" 1 3 |> Sub.copy = "bcd"
+ Sub.full "abcde" |> Sub.copy = "abcde"
+ *)
end
diff --git a/core/CCVector.ml b/src/core/CCVector.ml
similarity index 99%
rename from core/CCVector.ml
rename to src/core/CCVector.ml
index 143a5a55..f6cc9234 100644
--- a/core/CCVector.ml
+++ b/src/core/CCVector.ml
@@ -451,7 +451,7 @@ let of_seq ?(init=create ()) seq =
init
(*$T
- of_seq CCSequence.(1 -- 10) |> to_list = CCList.(1 -- 10)
+ of_seq Sequence.(1 -- 10) |> to_list = CCList.(1 -- 10)
*)
let to_seq v k = iter k v
@@ -524,7 +524,7 @@ let to_gen v =
) else None
(*$T
- let v = (1--10) in to_list v = CCGen.to_list (to_gen v)
+ let v = (1--10) in to_list v = Gen.to_list (to_gen v)
*)
let of_klist ?(init=create ()) l =
diff --git a/core/CCVector.mli b/src/core/CCVector.mli
similarity index 100%
rename from core/CCVector.mli
rename to src/core/CCVector.mli
diff --git a/src/core/META b/src/core/META
new file mode 100644
index 00000000..f90c5b91
--- /dev/null
+++ b/src/core/META
@@ -0,0 +1,129 @@
+# OASIS_START
+# DO NOT EDIT (digest: 9c70d2a3b15d841d97052a6ac9fe3a5f)
+version = "0.7"
+description = "A modular standard library focused on data structures."
+requires = "bytes"
+archive(byte) = "containers.cma"
+archive(byte, plugin) = "containers.cma"
+archive(native) = "containers.cmxa"
+archive(native, plugin) = "containers.cmxs"
+exists_if = "containers.cma"
+package "thread" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "containers threads"
+ archive(byte) = "containers_thread.cma"
+ archive(byte, plugin) = "containers_thread.cma"
+ archive(native) = "containers_thread.cmxa"
+ archive(native, plugin) = "containers_thread.cmxs"
+ exists_if = "containers_thread.cma"
+)
+
+package "string" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ archive(byte) = "containers_string.cma"
+ archive(byte, plugin) = "containers_string.cma"
+ archive(native) = "containers_string.cmxa"
+ archive(native, plugin) = "containers_string.cmxs"
+ exists_if = "containers_string.cma"
+)
+
+package "sexp" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "bytes"
+ archive(byte) = "containers_sexp.cma"
+ archive(byte, plugin) = "containers_sexp.cma"
+ archive(native) = "containers_sexp.cmxa"
+ archive(native, plugin) = "containers_sexp.cmxs"
+ exists_if = "containers_sexp.cma"
+)
+
+package "pervasives" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "containers"
+ archive(byte) = "containers_pervasives.cma"
+ archive(byte, plugin) = "containers_pervasives.cma"
+ archive(native) = "containers_pervasives.cmxa"
+ archive(native, plugin) = "containers_pervasives.cmxs"
+ exists_if = "containers_pervasives.cma"
+)
+
+package "misc" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "containers containers.data"
+ archive(byte) = "containers_misc.cma"
+ archive(byte, plugin) = "containers_misc.cma"
+ archive(native) = "containers_misc.cmxa"
+ archive(native, plugin) = "containers_misc.cmxs"
+ exists_if = "containers_misc.cma"
+)
+
+package "lwt" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "containers lwt containers.misc"
+ archive(byte) = "containers_lwt.cma"
+ archive(byte, plugin) = "containers_lwt.cma"
+ archive(native) = "containers_lwt.cmxa"
+ archive(native, plugin) = "containers_lwt.cmxs"
+ exists_if = "containers_lwt.cma"
+)
+
+package "iter" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ archive(byte) = "containers_iter.cma"
+ archive(byte, plugin) = "containers_iter.cma"
+ archive(native) = "containers_iter.cmxa"
+ archive(native, plugin) = "containers_iter.cmxs"
+ exists_if = "containers_iter.cma"
+)
+
+package "io" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "bytes"
+ archive(byte) = "containers_io.cma"
+ archive(byte, plugin) = "containers_io.cma"
+ archive(native) = "containers_io.cmxa"
+ archive(native, plugin) = "containers_io.cmxs"
+ exists_if = "containers_io.cma"
+)
+
+package "data" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ archive(byte) = "containers_data.cma"
+ archive(byte, plugin) = "containers_data.cma"
+ archive(native) = "containers_data.cmxa"
+ archive(native, plugin) = "containers_data.cmxs"
+ exists_if = "containers_data.cma"
+)
+
+package "bigarray" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "containers bigarray bytes"
+ archive(byte) = "containers_bigarray.cma"
+ archive(byte, plugin) = "containers_bigarray.cma"
+ archive(native) = "containers_bigarray.cmxa"
+ archive(native, plugin) = "containers_bigarray.cmxs"
+ exists_if = "containers_bigarray.cma"
+)
+
+package "advanced" (
+ version = "0.7"
+ description = "A modular standard library focused on data structures."
+ requires = "containers sequence"
+ archive(byte) = "containers_advanced.cma"
+ archive(byte, plugin) = "containers_advanced.cma"
+ archive(native) = "containers_advanced.cmxa"
+ archive(native, plugin) = "containers_advanced.cmxs"
+ exists_if = "containers_advanced.cma"
+)
+# OASIS_STOP
+
diff --git a/core/_tags b/src/core/_tags
similarity index 100%
rename from core/_tags
rename to src/core/_tags
diff --git a/src/core/containers.mldylib b/src/core/containers.mldylib
new file mode 100644
index 00000000..59800ccf
--- /dev/null
+++ b/src/core/containers.mldylib
@@ -0,0 +1,21 @@
+# OASIS_START
+# DO NOT EDIT (digest: c6788a9242c3a4f65df901507a530eee)
+CCVector
+CCPrint
+CCError
+CCHeap
+CCList
+CCOpt
+CCPair
+CCFun
+CCHash
+CCInt
+CCBool
+CCFloat
+CCArray
+CCOrd
+CCRandom
+CCString
+CCHashtbl
+CCMap
+# OASIS_STOP
diff --git a/src/core/containers.mllib b/src/core/containers.mllib
new file mode 100644
index 00000000..59800ccf
--- /dev/null
+++ b/src/core/containers.mllib
@@ -0,0 +1,21 @@
+# OASIS_START
+# DO NOT EDIT (digest: c6788a9242c3a4f65df901507a530eee)
+CCVector
+CCPrint
+CCError
+CCHeap
+CCList
+CCOpt
+CCPair
+CCFun
+CCHash
+CCInt
+CCBool
+CCFloat
+CCArray
+CCOrd
+CCRandom
+CCString
+CCHashtbl
+CCMap
+# OASIS_STOP
diff --git a/core/CCBV.ml b/src/data/CCBV.ml
similarity index 98%
rename from core/CCBV.ml
rename to src/data/CCBV.ml
index 37eeebb2..ac31693c 100644
--- a/core/CCBV.ml
+++ b/src/data/CCBV.ml
@@ -172,7 +172,7 @@ let iter_true bv f =
done
(*$T
- of_list [1;5;7] |> iter_true |> CCSequence.to_list |> List.sort CCOrd.compare = [1;5;7]
+ of_list [1;5;7] |> iter_true |> Sequence.to_list |> List.sort CCOrd.compare = [1;5;7]
*)
let to_list bv =
diff --git a/core/CCBV.mli b/src/data/CCBV.mli
similarity index 100%
rename from core/CCBV.mli
rename to src/data/CCBV.mli
diff --git a/core/CCCache.ml b/src/data/CCCache.ml
similarity index 100%
rename from core/CCCache.ml
rename to src/data/CCCache.ml
diff --git a/core/CCCache.mli b/src/data/CCCache.mli
similarity index 100%
rename from core/CCCache.mli
rename to src/data/CCCache.mli
diff --git a/core/CCDeque.ml b/src/data/CCDeque.ml
similarity index 100%
rename from core/CCDeque.ml
rename to src/data/CCDeque.ml
diff --git a/core/CCDeque.mli b/src/data/CCDeque.mli
similarity index 100%
rename from core/CCDeque.mli
rename to src/data/CCDeque.mli
diff --git a/core/CCFQueue.ml b/src/data/CCFQueue.ml
similarity index 100%
rename from core/CCFQueue.ml
rename to src/data/CCFQueue.ml
diff --git a/core/CCFQueue.mli b/src/data/CCFQueue.mli
similarity index 100%
rename from core/CCFQueue.mli
rename to src/data/CCFQueue.mli
diff --git a/core/CCFlatHashtbl.ml b/src/data/CCFlatHashtbl.ml
similarity index 100%
rename from core/CCFlatHashtbl.ml
rename to src/data/CCFlatHashtbl.ml
diff --git a/core/CCFlatHashtbl.mli b/src/data/CCFlatHashtbl.mli
similarity index 100%
rename from core/CCFlatHashtbl.mli
rename to src/data/CCFlatHashtbl.mli
diff --git a/misc/mixtbl.ml b/src/data/CCMixtbl.ml
similarity index 100%
rename from misc/mixtbl.ml
rename to src/data/CCMixtbl.ml
diff --git a/misc/mixtbl.mli b/src/data/CCMixtbl.mli
similarity index 84%
rename from misc/mixtbl.mli
rename to src/data/CCMixtbl.mli
index 650c0ab6..67af7755 100644
--- a/misc/mixtbl.mli
+++ b/src/data/CCMixtbl.mli
@@ -29,27 +29,27 @@ From https://github.com/mjambon/mixtbl , thanks to him.
Example:
{[
-let inj_int = Mixtbl.access () ;;
+let inj_int = CCMixtbl.access () ;;
-let tbl = Mixtbl.create 10 ;;
+let tbl = CCMixtbl.create 10 ;;
-OUnit.assert_equal None (Mixtbl.get ~inj:inj_int tbl "a");;
+OUnit.assert_equal None (CCMixtbl.get ~inj:inj_int tbl "a");;
-Mixtbl.set inj_int tbl "a" 1;;
+CCMixtbl.set inj_int tbl "a" 1;;
-OUnit.assert_equal (Some 1) (Mixtbl.get ~inj:inj_int tbl "a");;
+OUnit.assert_equal (Some 1) (CCMixtbl.get ~inj:inj_int tbl "a");;
-let inj_string = Mixtbl.access () ;;
+let inj_string = CCMixtbl.access () ;;
-Mixtbl.set inj_string tbl "b" "Hello";
+CCMixtbl.set inj_string tbl "b" "Hello";
-OUnit.assert_equal (Some "Hello") (Mixtbl.get inj_string tbl "b");;
-OUnit.assert_equal None (Mixtbl.get inj_string tbl "a");;
-OUnit.assert_equal (Some 1) (Mixtbl.get inj_int tbl "a");;
-Mixtbl.set inj_string tbl "a" "Bye";;
+OUnit.assert_equal (Some "Hello") (CCMixtbl.get inj_string tbl "b");;
+OUnit.assert_equal None (CCMixtbl.get inj_string tbl "a");;
+OUnit.assert_equal (Some 1) (CCMixtbl.get inj_int tbl "a");;
+CCMixtbl.set inj_string tbl "a" "Bye";;
-OUnit.assert_equal None (Mixtbl.get inj_int tbl "a");;
-OUnit.assert_equal (Some "Bye") (Mixtbl.get inj_string tbl "a");;
+OUnit.assert_equal None (CCMixtbl.get inj_int tbl "a");;
+OUnit.assert_equal (Some "Bye") (CCMixtbl.get inj_string tbl "a");;
]}
@since 0.6 *)
diff --git a/core/CCMultiMap.ml b/src/data/CCMultiMap.ml
similarity index 100%
rename from core/CCMultiMap.ml
rename to src/data/CCMultiMap.ml
diff --git a/core/CCMultiMap.mli b/src/data/CCMultiMap.mli
similarity index 100%
rename from core/CCMultiMap.mli
rename to src/data/CCMultiMap.mli
diff --git a/core/CCMultiSet.ml b/src/data/CCMultiSet.ml
similarity index 100%
rename from core/CCMultiSet.ml
rename to src/data/CCMultiSet.ml
diff --git a/core/CCMultiSet.mli b/src/data/CCMultiSet.mli
similarity index 100%
rename from core/CCMultiSet.mli
rename to src/data/CCMultiSet.mli
diff --git a/core/CCPersistentHashtbl.ml b/src/data/CCPersistentHashtbl.ml
similarity index 100%
rename from core/CCPersistentHashtbl.ml
rename to src/data/CCPersistentHashtbl.ml
diff --git a/core/CCPersistentHashtbl.mli b/src/data/CCPersistentHashtbl.mli
similarity index 100%
rename from core/CCPersistentHashtbl.mli
rename to src/data/CCPersistentHashtbl.mli
diff --git a/core/CCTrie.ml b/src/data/CCTrie.ml
similarity index 100%
rename from core/CCTrie.ml
rename to src/data/CCTrie.ml
diff --git a/core/CCTrie.mli b/src/data/CCTrie.mli
similarity index 100%
rename from core/CCTrie.mli
rename to src/data/CCTrie.mli
diff --git a/src/data/containers_data.mldylib b/src/data/containers_data.mldylib
new file mode 100644
index 00000000..90d1274e
--- /dev/null
+++ b/src/data/containers_data.mldylib
@@ -0,0 +1,13 @@
+# OASIS_START
+# DO NOT EDIT (digest: 5103c22b99ffdda9689659d2fbcfc489)
+CCMultiMap
+CCMultiSet
+CCTrie
+CCFlatHashtbl
+CCCache
+CCPersistentHashtbl
+CCDeque
+CCFQueue
+CCBV
+CCMixtbl
+# OASIS_STOP
diff --git a/src/data/containers_data.mllib b/src/data/containers_data.mllib
new file mode 100644
index 00000000..90d1274e
--- /dev/null
+++ b/src/data/containers_data.mllib
@@ -0,0 +1,13 @@
+# OASIS_START
+# DO NOT EDIT (digest: 5103c22b99ffdda9689659d2fbcfc489)
+CCMultiMap
+CCMultiSet
+CCTrie
+CCFlatHashtbl
+CCCache
+CCPersistentHashtbl
+CCDeque
+CCFQueue
+CCBV
+CCMixtbl
+# OASIS_STOP
diff --git a/core/CCIO.ml b/src/io/CCIO.ml
similarity index 80%
rename from core/CCIO.ml
rename to src/io/CCIO.ml
index b833275f..61f64cbb 100644
--- a/core/CCIO.ml
+++ b/src/io/CCIO.ml
@@ -28,6 +28,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
type 'a gen = unit -> 'a option (** See {!CCGen} *)
+let gen_singleton x =
+ let done_ = ref false in
+ fun () -> if !done_ then None else (done_ := true; Some x)
+
+let gen_filter_map f gen =
+ (* tailrec *)
+ let rec next () =
+ match gen() with
+ | None -> None
+ | Some x ->
+ match f x with
+ | None -> next()
+ | (Some _) as res -> res
+ in next
+
+let gen_of_array arr =
+ let r = ref 0 in
+ fun () ->
+ if !r = Array.length arr then None
+ else (
+ let x = arr.(!r) in
+ incr r;
+ Some x
+ )
+
+let gen_flat_map f next_elem =
+ let state = ref `Init in
+ let rec next() =
+ match !state with
+ | `Init -> get_next_gen()
+ | `Run gen ->
+ begin match gen () with
+ | None -> get_next_gen ()
+ | (Some _) as x -> x
+ end
+ | `Stop -> None
+ and get_next_gen() = match next_elem() with
+ | None -> state:=`Stop; None
+ | Some x ->
+ try state := `Run (f x); next()
+ with e -> state := `Stop; raise e
+ in
+ next
+
let with_in ?(mode=0o644) ?(flags=[]) filename f =
let ic = open_in_gen flags mode filename in
try
@@ -72,16 +116,14 @@ let read_lines_l ic =
with End_of_file ->
List.rev !l
-let read_all ic =
- let buf = ref (Bytes.create 256) in
+let read_all ?(size=1024) ic =
+ let buf = ref (Bytes.create size) in
let len = ref 0 in
try
while true do
(* resize *)
if !len = Bytes.length !buf then (
- let buf' = Bytes.create (2* !len) in
- Bytes.blit !buf 0 buf' 0 !len;
- buf := buf'
+ buf := Bytes.extend !buf 0 !len;
);
assert (Bytes.length !buf > !len);
let n = input ic !buf !len (Bytes.length !buf - !len) in
@@ -171,8 +213,8 @@ module File = struct
if Sys.is_directory d
then
let arr = Sys.readdir d in
- CCGen.of_array arr
- else CCGen.empty
+ gen_of_array arr
+ else fun () -> None
let cons_ x tl =
let first=ref true in
@@ -186,19 +228,19 @@ module File = struct
if Sys.is_directory d
then
let arr = Sys.readdir d in
- let tail = CCGen.of_array arr in
- let tail = CCGen.flat_map
+ let tail = gen_of_array arr in
+ let tail = gen_flat_map
(fun s -> walk (Filename.concat d s))
tail
in cons_ (`Dir,d) tail
- else CCGen.singleton (`File, d)
+ else gen_singleton (`File, d)
type walk_item = [`File | `Dir] * t
let read_dir ?(recurse=false) d =
if recurse
then
- CCGen.filter_map
+ gen_filter_map
(function
| `File, f -> Some f
| `Dir, _ -> None
diff --git a/core/CCIO.mli b/src/io/CCIO.mli
similarity index 95%
rename from core/CCIO.mli
rename to src/io/CCIO.mli
index 1e29f134..272e4ac0 100644
--- a/core/CCIO.mli
+++ b/src/io/CCIO.mli
@@ -29,9 +29,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Simple utilities to deal with basic Input/Output tasks in a resource-safe
way. For advanced IO tasks, the user is advised to use something
like Lwt or Async, that are far more comprehensive.
-This module depends on {!CCGen}.
-
-@since 0.6
{b NOTE} this was formerly a monadic IO module. The old module is now
in [containers.advanced] under the name [CCMonadIO].
@@ -50,15 +47,20 @@ Examples:
# CCIO.(
with_in "/tmp/input"
(fun ic ->
- with_out ~flags:[Open_creat] ~mode:0o644 "/tmp/output"
+ let chunks = read_chunks ic in
+ with_out ~flags:[Open_creat; Open_wronly] ~mode:0o644 "/tmp/output"
(fun oc ->
- Seq.chunks 512 ic |> Seq.to_output oc
+ write_gen oc chunks
)
)
) ;;
]}
+
+@since 0.6
+
*)
+
type 'a gen = unit -> 'a option (** See {!CCGen} *)
(** {2 Input} *)
@@ -82,8 +84,9 @@ val read_lines : in_channel -> string gen
val read_lines_l : in_channel -> string list
(** Read all lines into a list *)
-val read_all : in_channel -> string
-(** Read the whole channel into a buffer, then converted into a string *)
+val read_all : ?size:int -> in_channel -> string
+(** Read the whole channel into a buffer, then converted into a string.
+ @param size the internal buffer size @since 0.7 *)
(** {6 Output} *)
diff --git a/src/io/containers_io.mldylib b/src/io/containers_io.mldylib
new file mode 100644
index 00000000..54acdc47
--- /dev/null
+++ b/src/io/containers_io.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 60d34ed5d3f17d5a8ac1501b3c6db7e7)
+CCIO
+# OASIS_STOP
diff --git a/src/io/containers_io.mllib b/src/io/containers_io.mllib
new file mode 100644
index 00000000..54acdc47
--- /dev/null
+++ b/src/io/containers_io.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 60d34ed5d3f17d5a8ac1501b3c6db7e7)
+CCIO
+# OASIS_STOP
diff --git a/core/CCKList.ml b/src/iter/CCKList.ml
similarity index 100%
rename from core/CCKList.ml
rename to src/iter/CCKList.ml
diff --git a/core/CCKList.mli b/src/iter/CCKList.mli
similarity index 100%
rename from core/CCKList.mli
rename to src/iter/CCKList.mli
diff --git a/core/CCKTree.ml b/src/iter/CCKTree.ml
similarity index 100%
rename from core/CCKTree.ml
rename to src/iter/CCKTree.ml
diff --git a/core/CCKTree.mli b/src/iter/CCKTree.mli
similarity index 100%
rename from core/CCKTree.mli
rename to src/iter/CCKTree.mli
diff --git a/src/iter/containers_iter.mldylib b/src/iter/containers_iter.mldylib
new file mode 100644
index 00000000..de0a7859
--- /dev/null
+++ b/src/iter/containers_iter.mldylib
@@ -0,0 +1,5 @@
+# OASIS_START
+# DO NOT EDIT (digest: 2edfdbafae02fa6210e0c192d7250b1a)
+CCKTree
+CCKList
+# OASIS_STOP
diff --git a/src/iter/containers_iter.mllib b/src/iter/containers_iter.mllib
new file mode 100644
index 00000000..de0a7859
--- /dev/null
+++ b/src/iter/containers_iter.mllib
@@ -0,0 +1,5 @@
+# OASIS_START
+# DO NOT EDIT (digest: 2edfdbafae02fa6210e0c192d7250b1a)
+CCKTree
+CCKList
+# OASIS_STOP
diff --git a/src/lwt/containers_lwt.mldylib b/src/lwt/containers_lwt.mldylib
new file mode 100644
index 00000000..2cafc3b9
--- /dev/null
+++ b/src/lwt/containers_lwt.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: bc144ef7b5b54947fab9662a822f9179)
+Containers_lwt
+# OASIS_STOP
diff --git a/src/lwt/containers_lwt.mllib b/src/lwt/containers_lwt.mllib
new file mode 100644
index 00000000..2cafc3b9
--- /dev/null
+++ b/src/lwt/containers_lwt.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: bc144ef7b5b54947fab9662a822f9179)
+Containers_lwt
+# OASIS_STOP
diff --git a/src/lwt/containers_lwt.mlpack b/src/lwt/containers_lwt.mlpack
new file mode 100644
index 00000000..103df89d
--- /dev/null
+++ b/src/lwt/containers_lwt.mlpack
@@ -0,0 +1,5 @@
+# OASIS_START
+# DO NOT EDIT (digest: 90e18bcaee6d0b33210b35e709b0a41c)
+Lwt_automaton
+Lwt_actor
+# OASIS_STOP
diff --git a/lwt/lwt_actor.ml b/src/lwt/lwt_actor.ml
similarity index 100%
rename from lwt/lwt_actor.ml
rename to src/lwt/lwt_actor.ml
diff --git a/lwt/lwt_actor.mli b/src/lwt/lwt_actor.mli
similarity index 100%
rename from lwt/lwt_actor.mli
rename to src/lwt/lwt_actor.mli
diff --git a/lwt/lwt_automaton.ml b/src/lwt/lwt_automaton.ml
similarity index 100%
rename from lwt/lwt_automaton.ml
rename to src/lwt/lwt_automaton.ml
diff --git a/lwt/lwt_automaton.mli b/src/lwt/lwt_automaton.mli
similarity index 100%
rename from lwt/lwt_automaton.mli
rename to src/lwt/lwt_automaton.mli
diff --git a/misc/.merlin b/src/misc/.merlin
similarity index 100%
rename from misc/.merlin
rename to src/misc/.merlin
diff --git a/misc/AVL.ml b/src/misc/AVL.ml
similarity index 100%
rename from misc/AVL.ml
rename to src/misc/AVL.ml
diff --git a/misc/AVL.mli b/src/misc/AVL.mli
similarity index 100%
rename from misc/AVL.mli
rename to src/misc/AVL.mli
diff --git a/misc/CSM.ml b/src/misc/CSM.ml
similarity index 100%
rename from misc/CSM.ml
rename to src/misc/CSM.ml
diff --git a/misc/CSM.mli b/src/misc/CSM.mli
similarity index 100%
rename from misc/CSM.mli
rename to src/misc/CSM.mli
diff --git a/misc/RAL.ml b/src/misc/RAL.ml
similarity index 100%
rename from misc/RAL.ml
rename to src/misc/RAL.ml
diff --git a/misc/RAL.mli b/src/misc/RAL.mli
similarity index 100%
rename from misc/RAL.mli
rename to src/misc/RAL.mli
diff --git a/misc/absSet.ml b/src/misc/absSet.ml
similarity index 95%
rename from misc/absSet.ml
rename to src/misc/absSet.ml
index c8cbb06c..b8603320 100644
--- a/misc/absSet.ml
+++ b/src/misc/absSet.ml
@@ -25,6 +25,8 @@ for any direct, indirect, incidental, special, exemplary, or consequential
(** {1 Abstract set/relation} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t = {
mem : 'a -> bool;
iter : ('a -> unit) -> unit;
@@ -102,8 +104,7 @@ let product s1 s2 =
let cardinal () = s1.cardinal () * s2.cardinal () in
{ mem; iter; cardinal; }
-let to_seq set =
- CCSequence.from_iter (fun k -> set.iter k)
+let to_seq set k = set.iter k
let to_list set =
let l = ref [] in
@@ -154,7 +155,7 @@ let builder_cmp (type k) ?(cmp=Pervasives.compare) () =
mk_builder ~add ~get
let of_seq_builder ~builder seq =
- CCSequence.iter builder.add seq;
+ seq builder.add;
builder.get ()
let of_seq_hash ?eq ?hash seq =
@@ -165,7 +166,7 @@ let of_seq_cmp ?cmp seq =
let b = builder_cmp ?cmp () in
of_seq_builder b seq
-let of_list l = of_seq_hash (CCSequence.of_list l)
+let of_list l = of_seq_hash (fun k -> List.iter k l)
let map ?(builder=builder_hash ()) set ~f =
set.iter
@@ -202,7 +203,7 @@ module MakeHash(X : Hashtbl.HashedType) = struct
let of_seq ?(size=5) seq =
let h = Hashtbl.create size in
- CCSequence.iter (fun x -> Hashtbl.add h x ()) seq;
+ seq (fun x -> Hashtbl.add h x ());
let mem x = Hashtbl.mem h x in
let iter k = Hashtbl.iter (fun x () -> k x) h in
let cardinal () = Hashtbl.length h in
@@ -220,8 +221,9 @@ module MakeSet(S : Set.S) = struct
mk_generic ~cardinal ~mem ~iter
let of_seq ?(init=S.empty) seq =
- let set = CCSequence.fold (fun s x -> S.add x s) init seq in
- of_set set
+ let set = ref init in
+ seq (fun x -> set := S.add x !set);
+ of_set !set
let to_set set =
fold set S.empty (fun set x -> S.add x set)
diff --git a/misc/absSet.mli b/src/misc/absSet.mli
similarity index 93%
rename from misc/absSet.mli
rename to src/misc/absSet.mli
index 4bcec095..8ff8302a 100644
--- a/misc/absSet.mli
+++ b/src/misc/absSet.mli
@@ -25,6 +25,8 @@ for any direct, indirect, incidental, special, exemplary, or consequential
(** {1 Abstract set/relation} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t
val empty : 'a t
@@ -67,7 +69,7 @@ val intersection : 'a t -> 'a t -> 'a t
val product : 'a t -> 'b t -> ('a * 'b) t
(** Cartesian product *)
-val to_seq : 'a t -> 'a CCSequence.t
+val to_seq : 'a t -> 'a sequence
val to_list : 'a t -> 'a list
@@ -93,13 +95,13 @@ val builder_hash : ?size:int ->
val builder_cmp : ?cmp:('a -> 'a -> int) -> unit -> 'a builder
-val of_seq_builder : builder:'a builder -> 'a CCSequence.t -> 'a t
+val of_seq_builder : builder:'a builder -> 'a sequence -> 'a t
(** Uses the given builder to construct a set from a sequence of elements *)
-val of_seq_hash : ?eq:('a -> 'a -> bool) -> ?hash:('a -> int) -> 'a CCSequence.t -> 'a t
+val of_seq_hash : ?eq:('a -> 'a -> bool) -> ?hash:('a -> int) -> 'a sequence -> 'a t
(** Construction of a set from a sequence of hashable elements *)
-val of_seq_cmp : ?cmp:('a -> 'a -> int) -> 'a CCSequence.t -> 'a t
+val of_seq_cmp : ?cmp:('a -> 'a -> int) -> 'a sequence -> 'a t
(** Construction of a set from a sequence of comparable elements *)
val of_list : 'a list -> 'a t
@@ -133,7 +135,7 @@ module MakeHash(X : Hashtbl.HashedType) : sig
type elt = X.t
(** Elements of the set are hashable *)
- val of_seq : ?size:int -> elt CCSequence.t -> elt t
+ val of_seq : ?size:int -> elt sequence -> elt t
(** Build a set from a sequence *)
end
@@ -141,7 +143,7 @@ end
module MakeSet(S : Set.S) : sig
type elt = S.elt
- val of_seq : ?init:S.t -> elt CCSequence.t -> elt t
+ val of_seq : ?init:S.t -> elt sequence -> elt t
(** Build a set from a sequence *)
val of_set : S.t -> elt t
diff --git a/misc/automaton.ml b/src/misc/automaton.ml
similarity index 100%
rename from misc/automaton.ml
rename to src/misc/automaton.ml
diff --git a/misc/automaton.mli b/src/misc/automaton.mli
similarity index 100%
rename from misc/automaton.mli
rename to src/misc/automaton.mli
diff --git a/misc/bTree.ml b/src/misc/bTree.ml
similarity index 100%
rename from misc/bTree.ml
rename to src/misc/bTree.ml
diff --git a/misc/bTree.mli b/src/misc/bTree.mli
similarity index 100%
rename from misc/bTree.mli
rename to src/misc/bTree.mli
diff --git a/misc/bidir.ml b/src/misc/bidir.ml
similarity index 100%
rename from misc/bidir.ml
rename to src/misc/bidir.ml
diff --git a/misc/bidir.mli b/src/misc/bidir.mli
similarity index 100%
rename from misc/bidir.mli
rename to src/misc/bidir.mli
diff --git a/misc/bij.ml b/src/misc/bij.ml
similarity index 100%
rename from misc/bij.ml
rename to src/misc/bij.ml
diff --git a/misc/bij.mli b/src/misc/bij.mli
similarity index 100%
rename from misc/bij.mli
rename to src/misc/bij.mli
diff --git a/misc/cC.ml b/src/misc/cC.ml
similarity index 100%
rename from misc/cC.ml
rename to src/misc/cC.ml
diff --git a/misc/cC.mli b/src/misc/cC.mli
similarity index 100%
rename from misc/cC.mli
rename to src/misc/cC.mli
diff --git a/misc/cause.ml b/src/misc/cause.ml
similarity index 100%
rename from misc/cause.ml
rename to src/misc/cause.ml
diff --git a/misc/cause.mli b/src/misc/cause.mli
similarity index 100%
rename from misc/cause.mli
rename to src/misc/cause.mli
diff --git a/misc/circList.ml b/src/misc/circList.ml
similarity index 98%
rename from misc/circList.ml
rename to src/misc/circList.ml
index 9c795a98..0b0670be 100644
--- a/misc/circList.ml
+++ b/src/misc/circList.ml
@@ -124,7 +124,7 @@ let gen l =
(*$Q
(Q.list Q.small_int) (fun l -> \
l = [] || let q = of_list l in \
- gen q |> CCGen.take (List.length l) |> CCGen.to_list = l)
+ gen q |> Gen.take (List.length l) |> Gen.to_list = l)
*)
let seq l k =
diff --git a/misc/circList.mli b/src/misc/circList.mli
similarity index 100%
rename from misc/circList.mli
rename to src/misc/circList.mli
diff --git a/src/misc/containers_misc.mldylib b/src/misc/containers_misc.mldylib
new file mode 100644
index 00000000..551a3188
--- /dev/null
+++ b/src/misc/containers_misc.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 2df0608accd158542ebcb00720cfe599)
+Containers_misc
+# OASIS_STOP
diff --git a/src/misc/containers_misc.mllib b/src/misc/containers_misc.mllib
new file mode 100644
index 00000000..551a3188
--- /dev/null
+++ b/src/misc/containers_misc.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: 2df0608accd158542ebcb00720cfe599)
+Containers_misc
+# OASIS_STOP
diff --git a/src/misc/containers_misc.mlpack b/src/misc/containers_misc.mlpack
new file mode 100644
index 00000000..38299b17
--- /dev/null
+++ b/src/misc/containers_misc.mlpack
@@ -0,0 +1,33 @@
+# OASIS_START
+# DO NOT EDIT (digest: 9cd8890cc1fafa9902cc4f7f8f38c241)
+FHashtbl
+FlatHashtbl
+Hashset
+Heap
+LazyGraph
+PersistentGraph
+PHashtbl
+SkipList
+SplayTree
+SplayMap
+Univ
+Bij
+PiCalculus
+RAL
+UnionFind
+SmallSet
+AbsSet
+CSM
+TTree
+PrintBox
+HGraph
+Automaton
+Conv
+Bidir
+Iteratee
+BTree
+Ty
+Cause
+AVL
+ParseReact
+# OASIS_STOP
diff --git a/misc/conv.ml b/src/misc/conv.ml
similarity index 100%
rename from misc/conv.ml
rename to src/misc/conv.ml
diff --git a/misc/conv.mli b/src/misc/conv.mli
similarity index 100%
rename from misc/conv.mli
rename to src/misc/conv.mli
diff --git a/misc/fHashtbl.ml b/src/misc/fHashtbl.ml
similarity index 97%
rename from misc/fHashtbl.ml
rename to src/misc/fHashtbl.ml
index fe1b3ea2..a72dd203 100644
--- a/misc/fHashtbl.ml
+++ b/src/misc/fHashtbl.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Functional (persistent) hashtable} *)
+type 'a sequence = ('a -> unit) -> unit
+
(** {2 Signatures} *)
module type HASH = sig
@@ -64,9 +66,9 @@ module type S = sig
val size : 'a t -> int
(** Number of bindings *)
- val to_seq : 'a t -> (key * 'a) CCSequence.t
+ val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : ?size:int -> (key * 'a) CCSequence.t -> 'a t
+ val of_seq : ?size:int -> (key * 'a) sequence -> 'a t
end
(** {2 Persistent array} *)
@@ -336,13 +338,13 @@ module Tree(X : HASH) = struct
let size t =
fold (fun n _ _ -> n + 1) 0 t
- let to_seq t =
- CCSequence.from_iter (fun k -> iter (fun key value -> k (key, value)) t)
+ let to_seq t k =
+ iter (fun key value -> k (key, value)) t
let of_seq ?(size=32) seq =
- CCSequence.fold
- (fun t (k,v) -> replace t k v)
- (empty size) seq
+ let cur = ref (empty size) in
+ seq (fun (k,v) -> cur := replace !cur k v);
+ !cur
end
(** {2 Flat hashtable} *)
@@ -492,10 +494,10 @@ module Flat(X : HASH) = struct
| _ -> acc)
acc t.buckets
- let to_seq t =
- CCSequence.from_iter
- (fun k -> iter (fun key value -> k (key, value)) t)
+ let to_seq t k = iter (fun key value -> k (key, value)) t
let of_seq ?(size=32) seq =
- CCSequence.fold (fun t (k,v) -> replace t k v) (empty size) seq
+ let t = ref (empty size) in
+ seq (fun (k,v) -> t := replace !t k v);
+ !t
end
diff --git a/misc/fHashtbl.mli b/src/misc/fHashtbl.mli
similarity index 95%
rename from misc/fHashtbl.mli
rename to src/misc/fHashtbl.mli
index 9bb7ca4f..27866813 100644
--- a/misc/fHashtbl.mli
+++ b/src/misc/fHashtbl.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Functional (persistent) hashtable} *)
+type 'a sequence = ('a -> unit) -> unit
+
(** {2 Signatures} *)
module type HASH = sig
@@ -64,9 +66,9 @@ module type S = sig
val size : 'a t -> int
(** Number of bindings *)
- val to_seq : 'a t -> (key * 'a) CCSequence.t
+ val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : ?size:int -> (key * 'a) CCSequence.t -> 'a t
+ val of_seq : ?size:int -> (key * 'a) sequence -> 'a t
end
(** {2 Persistent array} *)
diff --git a/misc/flatHashtbl.ml b/src/misc/flatHashtbl.ml
similarity index 96%
rename from misc/flatHashtbl.ml
rename to src/misc/flatHashtbl.ml
index b2e2ce8d..1ff59a21 100644
--- a/misc/flatHashtbl.ml
+++ b/src/misc/flatHashtbl.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** Open addressing hashtable, with linear probing. *)
+type 'a sequence = ('a -> unit) -> unit
+
module type S =
sig
type key
@@ -61,9 +63,9 @@ module type S =
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
(** Fold on bindings *)
- val to_seq : 'a t -> (key * 'a) CCSequence.t
+ val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : 'a t -> (key * 'a) CCSequence.t -> unit
+ val of_seq : 'a t -> (key * 'a) sequence -> unit
val stats : 'a t -> int * int * int * int * int * int
(** Cf Weak.S *)
@@ -218,12 +220,11 @@ module Make(H : Hashtbl.HashedType) =
| _ -> fold acc (i+1)
in fold acc 0
- let to_seq t =
- CCSequence.from_iter
- (fun k -> iter (fun key value -> k (key, value)) t)
+ let to_seq t k =
+ iter (fun key value -> k (key, value)) t
let of_seq t seq =
- CCSequence.iter (fun (k,v) -> replace t k v) seq
+ seq (fun (k,v) -> replace t k v)
(** Statistics on the table *)
let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1)
diff --git a/misc/flatHashtbl.mli b/src/misc/flatHashtbl.mli
similarity index 95%
rename from misc/flatHashtbl.mli
rename to src/misc/flatHashtbl.mli
index 44f2c1f4..55b462a7 100644
--- a/misc/flatHashtbl.mli
+++ b/src/misc/flatHashtbl.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** Open addressing hashtable, with linear probing. *)
+type 'a sequence = ('a -> unit) -> unit
+
module type S =
sig
type key
@@ -61,9 +63,9 @@ module type S =
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
(** Fold on bindings *)
- val to_seq : 'a t -> (key * 'a) CCSequence.t
+ val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : 'a t -> (key * 'a) CCSequence.t -> unit
+ val of_seq : 'a t -> (key * 'a) sequence -> unit
val stats : 'a t -> int * int * int * int * int * int
(** Cf Weak.S *)
diff --git a/misc/hGraph.ml b/src/misc/hGraph.ml
similarity index 100%
rename from misc/hGraph.ml
rename to src/misc/hGraph.ml
diff --git a/misc/hGraph.mli b/src/misc/hGraph.mli
similarity index 100%
rename from misc/hGraph.mli
rename to src/misc/hGraph.mli
diff --git a/misc/hashset.ml b/src/misc/hashset.ml
similarity index 91%
rename from misc/hashset.ml
rename to src/misc/hashset.ml
index 5ff54bfe..110e4994 100644
--- a/misc/hashset.ml
+++ b/src/misc/hashset.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Mutable polymorphic hash-set} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t = ('a, unit) PHashtbl.t
(** A set is a hashtable, with trivial values *)
@@ -49,11 +51,10 @@ let fold f acc set = PHashtbl.fold (fun acc x () -> f acc x) acc set
let filter p set = PHashtbl.filter (fun x () -> p x) set
-let to_seq set =
- CCSequence.from_iter (fun k -> iter k set)
+let to_seq set k = iter k set
let of_seq set seq =
- CCSequence.iter (fun x -> add set x) seq
+ seq (fun x -> add set x)
let union ?into (s1 : 'a t) (s2 : 'a t) =
let into = match into with
@@ -62,10 +63,13 @@ let union ?into (s1 : 'a t) (s2 : 'a t) =
of_seq into (to_seq s2);
into
+let seq_filter p seq k =
+ seq (fun x -> if p x then k x)
+
let inter ?into (s1 : 'a t) (s2 : 'a t) =
let into = match into with
| Some s -> s
| None -> empty ~eq:s1.PHashtbl.eq ~hash:s1.PHashtbl.hash (cardinal s1) in
(* add to [into] elements of [s1] that also belong to [s2] *)
- of_seq into (CCSequence.filter (fun x -> mem s2 x) (to_seq s1));
+ of_seq into (seq_filter (fun x -> mem s2 x) (to_seq s1));
into
diff --git a/misc/hashset.mli b/src/misc/hashset.mli
similarity index 94%
rename from misc/hashset.mli
rename to src/misc/hashset.mli
index 92af637f..f421c557 100644
--- a/misc/hashset.mli
+++ b/src/misc/hashset.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Mutable polymorphic hash-set} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t = ('a, unit) PHashtbl.t
(** A set is a hashtable, with trivial values *)
@@ -51,9 +53,9 @@ val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
val filter : ('a -> bool) -> 'a t -> unit
(** destructive filter (remove elements that do not satisfy the predicate) *)
-val to_seq : 'a t -> 'a CCSequence.t
+val to_seq : 'a t -> 'a sequence
-val of_seq : 'a t -> 'a CCSequence.t -> unit
+val of_seq : 'a t -> 'a sequence -> unit
val union : ?into:'a t -> 'a t -> 'a t -> 'a t
(** Set union. The result is stored in [into] *)
diff --git a/misc/heap.ml b/src/misc/heap.ml
similarity index 98%
rename from misc/heap.ml
rename to src/misc/heap.ml
index 1b7be900..7b402d51 100644
--- a/misc/heap.ml
+++ b/src/misc/heap.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative priority queue} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t = {
mutable tree : 'a tree;
cmp : 'a -> 'a -> int;
diff --git a/misc/heap.mli b/src/misc/heap.mli
similarity index 94%
rename from misc/heap.mli
rename to src/misc/heap.mli
index ba901f98..e9adee7c 100644
--- a/misc/heap.mli
+++ b/src/misc/heap.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative priority queue} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t
(** A heap containing values of type 'a *)
@@ -51,6 +53,6 @@ val iter : 'a t -> ('a -> unit) -> unit
val size : _ t -> int
-val to_seq : 'a t -> 'a CCSequence.t
+val to_seq : 'a t -> 'a sequence
-val of_seq : 'a t -> 'a CCSequence.t -> unit
+val of_seq : 'a t -> 'a sequence -> unit
diff --git a/misc/iteratee.ml b/src/misc/iteratee.ml
similarity index 100%
rename from misc/iteratee.ml
rename to src/misc/iteratee.ml
diff --git a/misc/iteratee.mli b/src/misc/iteratee.mli
similarity index 100%
rename from misc/iteratee.mli
rename to src/misc/iteratee.mli
diff --git a/misc/json.ml b/src/misc/json.ml
similarity index 100%
rename from misc/json.ml
rename to src/misc/json.ml
diff --git a/misc/json.mli b/src/misc/json.mli
similarity index 100%
rename from misc/json.mli
rename to src/misc/json.mli
diff --git a/misc/lazyGraph.ml b/src/misc/lazyGraph.ml
similarity index 88%
rename from misc/lazyGraph.ml
rename to src/misc/lazyGraph.ml
index 3a2f893a..6262096c 100644
--- a/misc/lazyGraph.ml
+++ b/src/misc/lazyGraph.ml
@@ -29,6 +29,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
a graph is always accessed from a given initial node (so only connected
components can be represented by a single value of type ('v,'e) t). *)
+type 'a sequence = ('a -> unit) -> unit
+
(** {2 Type definitions} *)
type ('id, 'v, 'e) t = {
@@ -41,7 +43,7 @@ type ('id, 'v, 'e) t = {
other vertices, or to Empty if the identifier is not part of the graph. *)
and ('id, 'v, 'e) node =
| Empty
- | Node of 'id * 'v * ('e * 'id) CCSequence.t
+ | Node of 'id * 'v * ('e * 'id) sequence
(** A single node of the graph, with outgoing edges *)
and ('id, 'e) path = ('id * 'e * 'id) list
(** A reverse path (from the last element of the path to the first). *)
@@ -56,7 +58,7 @@ let empty =
let singleton ?(eq=(=)) ?(hash=Hashtbl.hash) v label =
let force v' =
- if eq v v' then Node (v, label, CCSequence.empty) else Empty in
+ if eq v v' then Node (v, label, fun _ -> ()) else Empty in
{ force; eq; hash; }
let make ?(eq=(=)) ?(hash=Hashtbl.hash) force =
@@ -66,7 +68,7 @@ let from_fun ?(eq=(=)) ?(hash=Hashtbl.hash) f =
let force v =
match f v with
| None -> Empty
- | Some (l, edges) -> Node (v, l, CCSequence.of_list edges) in
+ | Some (l, edges) -> Node (v, l, fun k -> List.iter k edges) in
{ eq; hash; force; }
(** {2 Polymorphic map} *)
@@ -110,7 +112,7 @@ module Mutable = struct
let map = mk_map ~eq ~hash in
let force v =
try let node = map.map_get v in
- Node (v, node.mut_v, CCSequence.of_list node.mut_outgoing)
+ Node (v, node.mut_v, fun k -> List.iter k node.mut_outgoing)
with Not_found -> Empty in
let graph = { eq; hash; force; } in
map, graph
@@ -129,12 +131,10 @@ end
let from_enum ?(eq=(=)) ?(hash=Hashtbl.hash) ~vertices ~edges =
let g, lazy_g = Mutable.create ~eq ~hash () in
- CCSequence.iter
- (fun (v,label_v) -> Mutable.add_vertex g v label_v;)
- vertices;
- CCSequence.iter
- (fun (v1, e, v2) -> Mutable.add_edge g v1 e v2)
- edges;
+ vertices
+ (fun (v,label_v) -> Mutable.add_vertex g v label_v;);
+ edges
+ (fun (v1, e, v2) -> Mutable.add_edge g v1 e v2);
lazy_g
let from_list ?(eq=(=)) ?(hash=Hashtbl.hash) l =
@@ -174,11 +174,11 @@ module Full = struct
| [] -> false
let bfs_full graph vertices =
- CCSequence.from_iter (fun k ->
+ fun k ->
let explored = mk_map ~eq:graph.eq ~hash:graph.hash in
let id = ref 0 in
let q = Queue.create () in (* queue of nodes to explore *)
- CCSequence.iter (fun v -> Queue.push (FullEnter (v,[])) q) vertices;
+ vertices (fun v -> Queue.push (FullEnter (v,[])) q);
while not (Queue.is_empty q) do
match Queue.pop q with
| FullEnter (v', path) ->
@@ -188,11 +188,11 @@ module Full = struct
| Node (_, label, edges) ->
explored.map_add v' ();
(* explore neighbors *)
- CCSequence.iter
+ edges
(fun (e,v'') ->
let path' = (v'',e,v') :: path in
- Queue.push (FullFollowEdge path') q)
- edges;
+ Queue.push (FullFollowEdge path') q
+ );
(* exit node afterward *)
Queue.push (FullExit v') q;
(* return this vertex *)
@@ -213,17 +213,17 @@ module Full = struct
Queue.push (FullEnter (v'', path')) q;
k (MeetEdge (v'', e, v', EdgeForward))
end
- done)
+ done
(* TODO: use a set of nodes currently being explored, rather than
checking whether the node is in the path (should be faster) *)
let dfs_full graph vertices =
- CCSequence.from_iter (fun k ->
+ fun k ->
let explored = mk_map ~eq:graph.eq ~hash:graph.hash in
let id = ref 0 in
let s = Stack.create () in (* stack of nodes to explore *)
- CCSequence.iter (fun v -> Stack.push (FullEnter (v,[])) s) vertices;
+ vertices (fun v -> Stack.push (FullEnter (v,[])) s);
while not (Stack.is_empty s) do
match Stack.pop s with
| FullExit v' -> k (ExitVertex v')
@@ -237,10 +237,10 @@ module Full = struct
(* prepare to exit later *)
Stack.push (FullExit v') s;
(* explore neighbors *)
- CCSequence.iter
+ edges
(fun (e,v'') ->
- Stack.push (FullFollowEdge ((v'', e, v') :: path)) s)
- edges;
+ Stack.push (FullFollowEdge ((v'', e, v') :: path)) s
+ );
(* return this vertex *)
let i = !id in
incr id;
@@ -258,22 +258,28 @@ module Full = struct
Stack.push (FullEnter (v'', path')) s;
k (MeetEdge (v'', e, v', EdgeForward))
end
- done)
+ done
end
+let seq_filter_map f seq k =
+ seq (fun x -> match f x with
+ | None -> ()
+ | Some y -> k y
+ )
+
let bfs graph v =
- CCSequence.fmap
+ seq_filter_map
(function
| Full.EnterVertex (v, l, i, _) -> Some (v, l, i)
| _ -> None)
- (Full.bfs_full graph (CCSequence.singleton v))
+ (Full.bfs_full graph (fun k -> k v))
let dfs graph v =
- CCSequence.fmap
+ seq_filter_map
(function
| Full.EnterVertex (v, l, i, _) -> Some (v, l, i)
| _ -> None)
- (Full.dfs_full graph (CCSequence.singleton v))
+ (Full.dfs_full graph (fun k -> k v))
(** {3 Mutable heap} *)
module Heap = struct
@@ -342,7 +348,7 @@ let a_star graph
?(distance=(fun v1 e v2 -> 1.))
~goal
start =
- CCSequence.from_iter (fun k ->
+ fun k ->
(* map node -> 'came_from' cell *)
let nodes = mk_map ~eq:graph.eq ~hash:graph.hash in
(* priority queue for nodes to explore *)
@@ -376,7 +382,7 @@ let a_star graph
| Empty -> ()
| Node (_, label, edges) ->
(* explore neighbors *)
- CCSequence.iter
+ edges
(fun (e,v'') ->
let cost = dist +. distance v' e v'' +. heuristic v'' in
let cell' =
@@ -395,14 +401,20 @@ let a_star graph
Heap.insert h (cost, v'');
cell'.cf_cost <- cost; (* update best cost/path *)
cell'.cf_prev <- CFEdge (e, cell);
- end)
- edges;
+ end);
(* check whether the node we just explored is a goal node *)
if goal v'
(* found a goal node! yield it *)
then k (dist, mk_path nodes [] v')
end
- done)
+ done
+
+exception ExitHead
+let seq_head seq =
+ let r = ref None in
+ try
+ seq (fun x -> r := Some x; raise ExitHead); None
+ with ExitHead -> !r
(** Shortest path from the first node to the second one, according
to the given (positive!) distance function. The path is reversed,
@@ -413,22 +425,29 @@ let dijkstra graph ?on_explore ?(ignore=fun v -> false)
a_star graph ?on_explore ~ignore ~distance ~heuristic:(fun _ -> 0.)
~goal:(fun v -> graph.eq v v2) v1
in
- match CCSequence.to_list (CCSequence.take 1 paths) with
- | [] -> raise Not_found
- | [x] -> x
- | _ -> assert false
+ match seq_head paths with
+ | None -> raise Not_found
+ | Some x -> x
+
+exception ExitForall
+let seq_for_all p seq =
+ try
+ seq (fun x -> if not (p x) then raise ExitForall);
+ true
+ with ExitForall -> false
+
(** Is the subgraph explorable from the given vertex, a Directed
Acyclic Graph? *)
let is_dag graph v =
- CCSequence.for_all
+ seq_for_all
(function
| Full.MeetEdge (_, _, _, Full.EdgeBackward) -> false
| _ -> true)
- (Full.dfs_full graph (CCSequence.singleton v))
+ (Full.dfs_full graph (fun k -> k v))
let is_dag_full graph vs =
- CCSequence.for_all
+ seq_for_all
(function
| Full.MeetEdge (_, _, _, Full.EdgeBackward) -> false
| _ -> true)
@@ -443,9 +462,8 @@ let find_cycle graph v =
let cycle = ref [] in
try
let path_stack = Stack.create () in
- let seq = Full.dfs_full graph (CCSequence.singleton v) in
- CCSequence.iter
- (function
+ let seq = Full.dfs_full graph (fun k -> k v) in
+ seq (function
| Full.EnterVertex (_, _, _, path) ->
Stack.push path path_stack
| Full.ExitVertex _ ->
@@ -456,8 +474,8 @@ let find_cycle graph v =
let path = (v1, e, v2) :: path in
cycle := path;
raise Exit
- | Full.MeetEdge _ -> ())
- seq;
+ | Full.MeetEdge _ -> ()
+ );
raise Not_found
with Exit ->
!cycle
@@ -471,6 +489,9 @@ let rev_path p =
(** {2 Lazy transformations} *)
+let seq_map f seq k = seq (fun x -> k (f x))
+let seq_append s1 s2 k = s1 k; s2 k
+
let union ?(combine=fun x y -> x) g1 g2 =
let force v =
match g1.force v, g2.force v with
@@ -478,7 +499,7 @@ let union ?(combine=fun x y -> x) g1 g2 =
| ((Node _) as n), Empty -> n
| Empty, ((Node _) as n) -> n
| Node (_, l1, e1), Node (_, l2, e2) ->
- Node (v, combine l1 l2, CCSequence.append e1 e2)
+ Node (v, combine l1 l2, seq_append e1 e2)
in { eq=g1.eq; hash=g1.hash; force; }
let map ~vertices ~edges g =
@@ -486,10 +507,12 @@ let map ~vertices ~edges g =
match g.force v with
| Empty -> Empty
| Node (_, l, edges_enum) ->
- let edges_enum' = CCSequence.map (fun (e,v') -> (edges e), v') edges_enum in
+ let edges_enum' = seq_map (fun (e,v') -> (edges e), v') edges_enum in
Node (v, vertices l, edges_enum')
in { eq=g.eq; hash=g.hash; force; }
+let seq_flat_map f seq k = seq (fun x -> f x k)
+
(** Replace each vertex by some vertices. By mapping [v'] to [f v'=v1,...,vn],
whenever [v] ---e---> [v'], then [v --e--> vi] for i=1,...,n. *)
let flatMap f g =
@@ -497,24 +520,29 @@ let flatMap f g =
match g.force v with
| Empty -> Empty
| Node (_, l, edges_enum) ->
- let edges_enum' = CCSequence.flatMap
+ let edges_enum' = seq_flat_map
(fun (e, v') ->
- CCSequence.map (fun v'' -> e, v'') (f v'))
+ seq_map (fun v'' -> e, v'') (f v'))
edges_enum in
Node (v, l, edges_enum')
in { eq=g.eq; hash=g.hash; force; }
+let seq_filter p seq k = seq (fun x -> if p x then k x)
+
let filter ?(vertices=(fun v l -> true)) ?(edges=fun v1 e v2 -> true) g =
let force v =
match g.force v with
| Empty -> Empty
| Node (_, l, edges_enum) when vertices v l ->
(* filter out edges *)
- let edges_enum' = CCSequence.filter (fun (e,v') -> edges v e v') edges_enum in
+ let edges_enum' = seq_filter (fun (e,v') -> edges v e v') edges_enum in
Node (v, l, edges_enum')
| Node _ -> Empty (* filter out this vertex *)
in { eq=g.eq; hash=g.hash; force; }
+let seq_product s1 s2 k =
+ s1 (fun x -> s2 (fun y -> k(x,y)))
+
let product g1 g2 =
let force (v1,v2) =
match g1.force v1, g2.force v2 with
@@ -522,8 +550,8 @@ let product g1 g2 =
| _, Empty -> Empty
| Node (_, l1, edges1), Node (_, l2, edges2) ->
(* product of edges *)
- let edges = CCSequence.product edges1 edges2 in
- let edges = CCSequence.map (fun ((e1,v1'),(e2,v2')) -> ((e1,e2),(v1',v2'))) edges in
+ let edges = seq_product edges1 edges2 in
+ let edges = seq_map (fun ((e1,v1'),(e2,v2')) -> ((e1,e2),(v1',v2'))) edges in
Node ((v1,v2), (l1,l2), edges)
and eq (v1,v2) (v1',v2') =
g1.eq v1 v1' && g2.eq v2 v2'
@@ -574,7 +602,7 @@ module Dot = struct
(* print preamble *)
Format.fprintf formatter "@[digraph %s {@;" name;
(* traverse *)
- CCSequence.iter
+ events
(function
| Full.EnterVertex (v, attrs, _, _) ->
Format.fprintf formatter " @[%a %a;@]@." pp_vertex v
@@ -584,8 +612,8 @@ module Dot = struct
Format.fprintf formatter " @[%a -> %a %a;@]@."
pp_vertex v1 pp_vertex v2
(CCList.print ~start:"[" ~stop:"]" ~sep:"," print_attribute)
- attrs)
- events;
+ attrs
+ );
(* close *)
Format.fprintf formatter "}@]@;@?";
()
@@ -608,17 +636,17 @@ let divisors_graph =
if i > 2
then
let l = divisors [] 2 i in
- let edges = CCSequence.map (fun i -> (), i) (CCSequence.of_list l) in
+ let edges = seq_map (fun i -> (), i) (fun k -> List.iter k l) in
Node (i, i, edges)
else
- Node (i, i, CCSequence.empty)
+ Node (i, i, fun _ -> ())
in make force
let collatz_graph =
let force i =
if i mod 2 = 0
- then Node (i, i, CCSequence.singleton ((), i / 2))
- else Node (i, i, CCSequence.singleton ((), i * 3 + 1))
+ then Node (i, i, fun k -> k ((), i / 2))
+ else Node (i, i, fun k -> k ((), i * 3 + 1))
in make force
let collatz_graph_bis =
@@ -628,10 +656,10 @@ let collatz_graph_bis =
; false, i * 2 ] @
if i mod 3 = 1 then [false, (i-1)/3] else []
in
- Node (i, i, CCSequence.of_list l)
+ Node (i, i, fun k -> List.iter k l)
in make force
let heap_graph =
let force i =
- Node (i, i, CCSequence.of_list [(), 2*i; (), 2*i+1])
+ Node (i, i, fun k -> List.iter k [(), 2*i; (), 2*i+1])
in make force
diff --git a/misc/lazyGraph.mli b/src/misc/lazyGraph.mli
similarity index 92%
rename from misc/lazyGraph.mli
rename to src/misc/lazyGraph.mli
index 1b33d983..5c88d026 100644
--- a/misc/lazyGraph.mli
+++ b/src/misc/lazyGraph.mli
@@ -34,6 +34,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {2 Type definitions} *)
+type 'a sequence = ('a -> unit) -> unit
+
type ('id, 'v, 'e) t = {
eq : 'id -> 'id -> bool;
hash : 'id -> int;
@@ -44,7 +46,7 @@ type ('id, 'v, 'e) t = {
other vertices, or to Empty if the identifier is not part of the graph. *)
and ('id, 'v, 'e) node =
| Empty
- | Node of 'id * 'v * ('e * 'id) CCSequence.t
+ | Node of 'id * 'v * ('e * 'id) sequence
(** A single node of the graph, with outgoing edges *)
and ('id, 'e) path = ('id * 'e * 'id) list
(** A reverse path (from the last element of the path to the first). *)
@@ -70,8 +72,8 @@ val make : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) ->
(** Build a graph from the [force] function *)
val from_enum : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) ->
- vertices:('id * 'v) CCSequence.t ->
- edges:('id * 'e * 'id) CCSequence.t ->
+ vertices:('id * 'v) sequence ->
+ edges:('id * 'e * 'id) sequence ->
('id, 'v, 'e) t
(** Concrete (eager) representation of a Graph *)
@@ -117,21 +119,21 @@ module Full : sig
| EdgeBackward (* toward the current trail *)
| EdgeTransverse (* toward a totally explored part of the graph *)
- val bfs_full : ('id, 'v, 'e) t -> 'id CCSequence.t ->
- ('id, 'v, 'e) traverse_event CCSequence.t
+ val bfs_full : ('id, 'v, 'e) t -> 'id sequence ->
+ ('id, 'v, 'e) traverse_event sequence
(** Lazy traversal in breadth first from a finite set of vertices *)
- val dfs_full : ('id, 'v, 'e) t -> 'id CCSequence.t ->
- ('id, 'v, 'e) traverse_event CCSequence.t
+ val dfs_full : ('id, 'v, 'e) t -> 'id sequence ->
+ ('id, 'v, 'e) traverse_event sequence
(** Lazy traversal in depth first from a finite set of vertices *)
end
(** The traversal functions assign a unique ID to every traversed node *)
-val bfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) CCSequence.t
+val bfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) sequence
(** Lazy traversal in breadth first *)
-val dfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) CCSequence.t
+val dfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) sequence
(** Lazy traversal in depth first *)
module Heap : sig
@@ -149,7 +151,7 @@ val a_star : ('id, 'v, 'e) t ->
?distance:('id -> 'e -> 'id -> float) ->
goal:('id -> bool) ->
'id ->
- (float * ('id, 'e) path) CCSequence.t
+ (float * ('id, 'e) path) sequence
(** Shortest path from the first node to nodes that satisfy [goal], according
to the given (positive!) distance function. The distance is also returned.
[ignore] allows one to ignore some vertices during exploration.
@@ -174,7 +176,7 @@ val is_dag : ('id, _, _) t -> 'id -> bool
(** Is the subgraph explorable from the given vertex, a Directed
Acyclic Graph? *)
-val is_dag_full : ('id, _, _) t -> 'id CCSequence.t -> bool
+val is_dag_full : ('id, _, _) t -> 'id sequence -> bool
(** Is the Graph reachable from the given vertices, a DAG? See {! is_dag} *)
val find_cycle : ('id, _, 'e) t -> 'id -> ('id, 'e) path
@@ -196,7 +198,7 @@ val map : vertices:('v -> 'v2) -> edges:('e -> 'e2) ->
('id, 'v, 'e) t -> ('id, 'v2, 'e2) t
(** Map vertice and edge labels *)
-val flatMap : ('id -> 'id CCSequence.t) ->
+val flatMap : ('id -> 'id sequence) ->
('id, 'v, 'e) t ->
('id, 'v, 'e) t
(** Replace each vertex by some vertices. By mapping [v'] to [f v'=v1,...,vn],
@@ -231,12 +233,12 @@ module Dot : sig
val pp_enum : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) ->
name:string -> Format.formatter ->
- ('id,attribute list,attribute list) Full.traverse_event CCSequence.t ->
+ ('id,attribute list,attribute list) Full.traverse_event sequence ->
unit
val pp : name:string -> ('id, attribute list, attribute list) t ->
Format.formatter ->
- 'id CCSequence.t -> unit
+ 'id sequence -> unit
(** Pretty print the given graph (starting from the given set of vertices)
to the channel in DOT format *)
end
diff --git a/misc/pHashtbl.ml b/src/misc/pHashtbl.ml
similarity index 98%
rename from misc/pHashtbl.ml
rename to src/misc/pHashtbl.ml
index fc138ecf..86458bcf 100644
--- a/misc/pHashtbl.ml
+++ b/src/misc/pHashtbl.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Open addressing hashtable (robin hood hashing)} *)
+type 'a sequence = ('a -> unit) -> unit
+
type ('a, 'b) t = {
mutable buckets : ('a, 'b) bucket array;
mutable size : int;
@@ -77,7 +79,7 @@ let clear t =
(** Index of slot, for i-th probing starting from hash [h] in
a table of length [n] *)
let addr h n i = (h + i) mod n
-
+
(** Insert (key -> value) in table, starting with the hash. *)
let insert t key value =
let n = Array.length t.buckets in
@@ -217,12 +219,10 @@ let filter pred t =
(** Add the given pairs to the hashtable *)
let of_seq t seq =
- CCSequence.iter (fun (k,v) -> add t k v) seq
+ seq (fun (k,v) -> add t k v)
(** CCSequence of pairs *)
-let to_seq t =
- CCSequence.from_iter
- (fun kont -> iter (fun k v -> kont (k,v)) t)
+let to_seq t kont = iter (fun k v -> kont (k,v)) t
(** Statistics on the table *)
let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1)
diff --git a/misc/pHashtbl.mli b/src/misc/pHashtbl.mli
similarity index 95%
rename from misc/pHashtbl.mli
rename to src/misc/pHashtbl.mli
index d5d8bd54..2a9c82c1 100644
--- a/misc/pHashtbl.mli
+++ b/src/misc/pHashtbl.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Open addressing hashtable (robin hood hashing)} *)
+type 'a sequence = ('a -> unit) -> unit
+
type ('a, 'b) t = {
mutable buckets : ('a, 'b) bucket array;
mutable size : int;
@@ -90,11 +92,11 @@ val filter : ('a -> 'b -> bool) -> ('a, 'b) t -> unit
val fold : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t -> 'c
(** Fold on bindings *)
-val of_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t -> unit
+val of_seq : ('a, 'b) t -> ('a * 'b) sequence -> unit
(** Add the given pairs to the hashtable *)
-val to_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t
- (** CCSequence of pairs *)
+val to_seq : ('a, 'b) t -> ('a * 'b) sequence
+ (** Sequence of pairs *)
val stats : (_, _) t -> int * int * int * int * int * int
(** Cf Weak.S *)
diff --git a/misc/parseReact.ml b/src/misc/parseReact.ml
similarity index 99%
rename from misc/parseReact.ml
rename to src/misc/parseReact.ml
index d1eee788..99b7c12e 100644
--- a/misc/parseReact.ml
+++ b/src/misc/parseReact.ml
@@ -232,6 +232,6 @@ let run p seq =
<|> (skip_spaces >> exact '(' >> many1 ~sep:(exact ' ') (delay p) >>= fun l ->
skip_spaces >> exact ')' >> return (list_ l))
in
- let res = run (p ()) (CCSequence.of_str "(a b (c d))") in
+ let res = run (p ()) (Sequence.of_str "(a b (c d))") in
assert_equal res [list_ [atom "a"; atom "b"; list_ [atom "c"; atom "d"]]]
*)
diff --git a/misc/parseReact.mli b/src/misc/parseReact.mli
similarity index 100%
rename from misc/parseReact.mli
rename to src/misc/parseReact.mli
diff --git a/misc/persistentGraph.ml b/src/misc/persistentGraph.ml
similarity index 88%
rename from misc/persistentGraph.ml
rename to src/misc/persistentGraph.ml
index 1928e6f5..fb42ea08 100644
--- a/misc/persistentGraph.ml
+++ b/src/misc/persistentGraph.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 A simple polymorphic directed graph.} *)
+type 'a sequence = ('a -> unit) -> unit
+
type ('v, 'e) t = ('v, ('v, 'e) node) PHashtbl.t
(** Graph parametrized by a type for vertices, and one for edges *)
and ('v, 'e) node = {
@@ -83,25 +85,27 @@ let add t v1 e v2 =
()
let add_seq t seq =
- CCSequence.iter (fun (v1,e,v2) -> add t v1 e v2) seq
+ seq (fun (v1,e,v2) -> add t v1 e v2)
-let next t v =
- CCSequence.of_list (PHashtbl.find t v).n_next
+let next t v k =
+ List.iter k (PHashtbl.find t v).n_next
-let prev t v =
- CCSequence.of_list (PHashtbl.find t v).n_prev
+let prev t v k =
+ List.iter k (PHashtbl.find t v).n_prev
+
+let seq_map f seq k = seq (fun x -> k (f x))
+let seq_filter p seq k = seq (fun x -> if p x then k x)
let between t v1 v2 =
- let edges = CCSequence.of_list (PHashtbl.find t v1).n_next in
- let edges = CCSequence.filter (fun (e, v2') -> (PHashtbl.get_eq t) v2 v2') edges in
- CCSequence.map fst edges
+ let edges k = List.iter k (PHashtbl.find t v1).n_next in
+ let edges = seq_filter (fun (e, v2') -> (PHashtbl.get_eq t) v2 v2') edges in
+ seq_map fst edges
(** Call [k] on every vertex *)
let iter_vertices t k =
PHashtbl.iter (fun v _ -> k v) t
-let vertices t =
- CCSequence.from_iter (iter_vertices t)
+let vertices t = iter_vertices t
(** Call [k] on every edge *)
let iter t k =
@@ -109,27 +113,37 @@ let iter t k =
(fun v1 node -> List.iter (fun (e, v2) -> k (v1, e, v2)) node.n_next)
t
-let to_seq t =
- CCSequence.from_iter (iter t)
+let to_seq t = iter t
(** {2 Global operations} *)
+exception ExitIsEmpty
+let seq_is_empty seq =
+ try seq (fun _ -> raise ExitIsEmpty); true
+ with ExitIsEmpty -> false
+
(** Roots, ie vertices with no incoming edges *)
let roots g =
let vertices = vertices g in
- CCSequence.filter (fun v -> CCSequence.is_empty (prev g v)) vertices
+ seq_filter (fun v -> seq_is_empty (prev g v)) vertices
(** Leaves, ie vertices with no outgoing edges *)
let leaves g =
let vertices = vertices g in
- CCSequence.filter (fun v -> CCSequence.is_empty (next g v)) vertices
+ seq_filter (fun v -> seq_is_empty (next g v)) vertices
+
+exception ExitHead
+let seq_head seq =
+ let r = ref None in
+ try
+ seq (fun x -> r := Some x; raise ExitHead); None
+ with ExitHead -> !r
(** Pick a vertex, or raise Not_found *)
let choose g =
- match CCSequence.to_list (CCSequence.take 1 (vertices g)) with
- | [x] -> x
- | [] -> raise Not_found
- | _ -> assert false
+ match seq_head (vertices g) with
+ | Some x -> x
+ | None -> raise Not_found
let rev_edge (v,e,v') = (v',e,v)
@@ -155,14 +169,12 @@ let bfs graph first k =
(* yield current node *)
k v;
(* explore children *)
- CCSequence.iter
+ next graph v
(fun (e, v') -> if not (Hashset.mem explored v')
then (Hashset.add explored v'; Queue.push v' q))
- (next graph v)
done
-let bfs_seq graph first =
- CCSequence.from_iter (fun k -> bfs graph first k)
+let bfs_seq graph first k = bfs graph first k
(** DFS, with callbacks called on each encountered node and edge *)
let dfs_full graph ?(labels=mk_v_table graph)
@@ -183,7 +195,7 @@ first
(* enter the node *)
enter trail';
(* explore edges *)
- CCSequence.iter
+ next graph v
(fun (e, v') ->
try let n' = PHashtbl.find labels v' in
if n' < n && List.exists (fun (_,n'') -> n' = n'') trail'
@@ -192,8 +204,8 @@ first
fwd_edge (v,e,v') (* forward or cross edge *)
with Not_found ->
tree_edge (v,e,v'); (* tree edge *)
- explore trail' v') (* explore the subnode *)
- (next graph v);
+ explore trail' v' (* explore the subnode *)
+ );
(* exit the node *)
exit trail'
end
@@ -216,10 +228,10 @@ let is_dag g =
else try
let labels = mk_v_table g in
(* do a DFS from each root; any back edge indicates a cycle *)
- CCSequence.iter
+ vertices g
(fun v ->
- dfs_full g ~labels ~back_edge:(fun _ -> raise Exit) v)
- (vertices g);
+ dfs_full g ~labels ~back_edge:(fun _ -> raise Exit) v
+ );
true (* complete traversal without back edge *)
with Exit ->
false (* back edge detected! *)
@@ -259,14 +271,13 @@ let min_path_full (type v) (type e) graph
else begin
Hashset.add explored v;
(* explore successors *)
- CCSequence.iter
+ next graph v
(fun (e, v') ->
if Hashset.mem explored v' || ignore v' then ()
else
let cost_v' = (cost v e v') + cost_v in
let path' = (v',e,v) :: path in
Heap.insert q (v', cost_v', path'))
- (next graph v)
end
done;
(* if a satisfying path was found, Exit would have been raised *)
@@ -307,7 +318,7 @@ type attribute = [
(** Pretty print the graph in DOT, on given formatter. Using a sequence
allows to easily select which edges are important,
- or to combine several graphs with [CCSequence.append]. *)
+ or to combine several graphs with [seq_append]. *)
let pp ~name ?vertices
~(print_edge : 'v -> 'e -> 'v -> attribute list)
~(print_vertex : 'v -> attribute list) formatter (graph : ('v, 'e) t) =
@@ -341,14 +352,14 @@ let pp ~name ?vertices
(* print preamble *)
Format.fprintf formatter "@[digraph %s {@;" name;
(* print edges *)
- CCSequence.iter
+ to_seq graph
(fun (v1, e, v2) ->
let attributes = print_edge v1 e v2 in
Format.fprintf formatter " @[%a -> %a [%a];@]@."
pp_vertex v1 pp_vertex v2
(CCList.print ~sep:"," print_attribute)
- attributes)
- (to_seq graph);
+ attributes
+ );
(* print vertices *)
PHashtbl.iter
(fun v _ ->
diff --git a/misc/persistentGraph.mli b/src/misc/persistentGraph.mli
similarity index 90%
rename from misc/persistentGraph.mli
rename to src/misc/persistentGraph.mli
index 6c061706..8ec044cc 100644
--- a/misc/persistentGraph.mli
+++ b/src/misc/persistentGraph.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 A simple polymorphic directed graph.} *)
+type 'a sequence = ('a -> unit) -> unit
+
(** {2 Basics} *)
type ('v, 'e) t
@@ -51,31 +53,31 @@ val length : (_, _) t -> int
val add : ('v,'e) t -> 'v -> 'e -> 'v -> unit
(** Add an edge between two vertices *)
-val add_seq : ('v,'e) t -> ('v * 'e * 'v) CCSequence.t -> unit
+val add_seq : ('v,'e) t -> ('v * 'e * 'v) sequence -> unit
(** Add the vertices to the graph *)
-val next : ('v, 'e) t -> 'v -> ('e * 'v) CCSequence.t
+val next : ('v, 'e) t -> 'v -> ('e * 'v) sequence
(** Outgoing edges *)
-val prev : ('v, 'e) t -> 'v -> ('e * 'v) CCSequence.t
+val prev : ('v, 'e) t -> 'v -> ('e * 'v) sequence
(** Incoming edges *)
-val between : ('v, 'e) t -> 'v -> 'v -> 'e CCSequence.t
+val between : ('v, 'e) t -> 'v -> 'v -> 'e sequence
val iter_vertices : ('v, 'e) t -> ('v -> unit) -> unit
-val vertices : ('v, 'e) t -> 'v CCSequence.t
+val vertices : ('v, 'e) t -> 'v sequence
(** Iterate on vertices *)
val iter : ('v, 'e) t -> ('v * 'e * 'v -> unit) -> unit
-val to_seq : ('v, 'e) t -> ('v * 'e * 'v) CCSequence.t
+val to_seq : ('v, 'e) t -> ('v * 'e * 'v) sequence
(** Dump the graph as a sequence of vertices *)
(** {2 Global operations} *)
-val roots : ('v, 'e) t -> 'v CCSequence.t
+val roots : ('v, 'e) t -> 'v sequence
(** Roots, ie vertices with no incoming edges *)
-val leaves : ('v, 'e) t -> 'v CCSequence.t
+val leaves : ('v, 'e) t -> 'v sequence
(** Leaves, ie vertices with no outgoing edges *)
val choose : ('v, 'e) t -> 'v
@@ -92,8 +94,8 @@ val rev : ('v, 'e) t -> unit
val bfs : ('v, 'e) t -> 'v -> ('v -> unit) -> unit
(** Breadth-first search, from given 'v *)
-val bfs_seq : ('v, 'e) t -> 'v -> 'v CCSequence.t
- (** CCSequence of vertices traversed during breadth-first search *)
+val bfs_seq : ('v, 'e) t -> 'v -> 'v sequence
+ (** Sequence of vertices traversed during breadth-first search *)
val dfs_full : ('v, 'e) t ->
?labels:('v, int) PHashtbl.t ->
diff --git a/misc/piCalculus.ml b/src/misc/piCalculus.ml
similarity index 100%
rename from misc/piCalculus.ml
rename to src/misc/piCalculus.ml
diff --git a/misc/piCalculus.mli b/src/misc/piCalculus.mli
similarity index 100%
rename from misc/piCalculus.mli
rename to src/misc/piCalculus.mli
diff --git a/misc/printBox.ml b/src/misc/printBox.ml
similarity index 100%
rename from misc/printBox.ml
rename to src/misc/printBox.ml
diff --git a/misc/printBox.mli b/src/misc/printBox.mli
similarity index 100%
rename from misc/printBox.mli
rename to src/misc/printBox.mli
diff --git a/misc/puf.ml b/src/misc/puf.ml
similarity index 100%
rename from misc/puf.ml
rename to src/misc/puf.ml
diff --git a/misc/puf.mli b/src/misc/puf.mli
similarity index 100%
rename from misc/puf.mli
rename to src/misc/puf.mli
diff --git a/misc/skipList.ml b/src/misc/skipList.ml
similarity index 97%
rename from misc/skipList.ml
rename to src/misc/skipList.ml
index 60db79a6..c9af6a63 100644
--- a/misc/skipList.ml
+++ b/src/misc/skipList.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative skip-list} *)
+type 'a gen = unit -> 'a option
+
(** Most functions are inspired from
"A skip list cookbook", William Pugh, 1989. *)
@@ -187,6 +189,10 @@ let gen l =
x := a.(0);
Some (k, !v)
+let rec gen_iter f g = match g() with
+ | None -> ()
+ | Some x -> f x; gen_iter f g
+
(** Add content of the iterator to the list *)
let of_gen l gen =
- CCGen.iter (fun (k,v) -> add l k v) gen
+ gen_iter (fun (k,v) -> add l k v) gen
diff --git a/misc/skipList.mli b/src/misc/skipList.mli
similarity index 94%
rename from misc/skipList.mli
rename to src/misc/skipList.mli
index 42b357c9..d701e4b9 100644
--- a/misc/skipList.mli
+++ b/src/misc/skipList.mli
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative skip-list} *)
+type 'a gen = unit -> 'a option
+
type ('a, 'b) t
(** A skip list that maps elements of type 'a to elements of type 'b *)
@@ -53,6 +55,6 @@ val remove : ('a, 'b) t -> 'a -> unit
val length : (_, _) t -> int
(** Number of elements *)
-val gen : ('a, 'b) t -> ('a * 'b) CCGen.t
+val gen : ('a, 'b) t -> ('a * 'b) gen
-val of_gen : ('a, 'b) t -> ('a * 'b) CCGen.t -> unit
+val of_gen : ('a, 'b) t -> ('a * 'b) gen -> unit
diff --git a/misc/smallSet.ml b/src/misc/smallSet.ml
similarity index 94%
rename from misc/smallSet.ml
rename to src/misc/smallSet.ml
index 24b5ae69..23082bfa 100644
--- a/misc/smallSet.ml
+++ b/src/misc/smallSet.ml
@@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Small set structure} *)
+type 'a sequence = ('a -> unit) -> unit
+
type 'a t = {
cmp : 'a -> 'a -> int;
nodes : 'a node;
@@ -123,11 +125,15 @@ let to_seq set =
iter k set
let of_seq set seq =
- CCSequence.fold add set seq
+ let set = ref set in
+ seq (fun x -> set := add !set x);
+ !set
let to_list set =
- CCSequence.to_rev_list (to_seq set)
+ let l = ref [] in
+ to_seq set (fun x -> l := x :: !l);
+ !l
let of_list set l =
- of_seq set (CCSequence.of_list l)
+ List.fold_left add set l
diff --git a/misc/smallSet.mli b/src/misc/smallSet.mli
similarity index 94%
rename from misc/smallSet.mli
rename to src/misc/smallSet.mli
index 1582b5e8..0a46593e 100644
--- a/misc/smallSet.mli
+++ b/src/misc/smallSet.mli
@@ -29,6 +29,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function. It is implemented as a sorted list, so most operations
are in linear time. *)
+type 'a sequence = ('a -> unit) -> unit
+
+
type 'a t
(** Set of elements of type 'a *)
@@ -59,9 +62,9 @@ val iter : ('a -> unit) -> 'a t -> unit
val size : _ t -> int
(** Number of elements *)
-val to_seq : 'a t -> 'a CCSequence.t
+val to_seq : 'a t -> 'a sequence
-val of_seq : 'a t -> 'a CCSequence.t -> 'a t
+val of_seq : 'a t -> 'a sequence -> 'a t
val to_list : 'a t -> 'a list
diff --git a/misc/splayMap.ml b/src/misc/splayMap.ml
similarity index 96%
rename from misc/splayMap.ml
rename to src/misc/splayMap.ml
index 5e6465f9..4a9de67d 100644
--- a/misc/splayMap.ml
+++ b/src/misc/splayMap.ml
@@ -29,6 +29,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://www.cs.cornell.edu/Courses/cs3110/2009fa/recitations/rec-splay.html
*)
+type 'a sequence = ('a -> unit) -> unit
+
(** {2 Polymorphic Maps} *)
type ('a, 'b) t = {
@@ -192,11 +194,12 @@ let choose t =
| Node (k, v, _, _) -> k, v
let to_seq t =
- CCSequence.from_iter
- (fun kont -> iter t (fun k v -> kont (k, v)))
+ fun kont -> iter t (fun k v -> kont (k, v))
let of_seq t seq =
- CCSequence.fold (fun t (k, v) -> add t k v) t seq
+ let t = ref t in
+ seq (fun (k, v) -> t := add !t k v);
+ !t
(** {2 Functorial interface} *)
@@ -238,9 +241,9 @@ module type S = sig
val choose : 'a t -> (key * 'a)
(** Some binding, or raises Not_found *)
- val to_seq : 'a t -> (key * 'a) CCSequence.t
+ val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : 'a t -> (key * 'a) CCSequence.t -> 'a t
+ val of_seq : 'a t -> (key * 'a) sequence -> 'a t
end
module type ORDERED = sig
@@ -404,9 +407,10 @@ module Make(X : ORDERED) = struct
| Node (k, v, _, _) -> k, v
let to_seq t =
- CCSequence.from_iter
- (fun kont -> iter t (fun k v -> kont (k, v)))
+ fun kont -> iter t (fun k v -> kont (k, v))
let of_seq t seq =
- CCSequence.fold (fun t (k, v) -> add t k v) t seq
+ let t = ref t in
+ seq (fun (k, v) -> t := add !t k v);
+ !t
end
diff --git a/misc/splayMap.mli b/src/misc/splayMap.mli
similarity index 93%
rename from misc/splayMap.mli
rename to src/misc/splayMap.mli
index 8d591977..6733f506 100644
--- a/misc/splayMap.mli
+++ b/src/misc/splayMap.mli
@@ -28,6 +28,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(* TODO: map-wide operations: merge, compare, equal, for_all, exists,
batch (sorted) add, partition, split, max_elt, min_elt, map... *)
+type 'a sequence = ('a -> unit) -> unit
+
+
(** {2 Polymorphic Maps} *)
type ('a, 'b) t
@@ -69,9 +72,9 @@ val size : (_, _) t -> int
val choose : ('a, 'b) t -> ('a * 'b)
(** Some binding, or raises Not_found *)
-val to_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t
+val to_seq : ('a, 'b) t -> ('a * 'b) sequence
-val of_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t -> ('a, 'b) t
+val of_seq : ('a, 'b) t -> ('a * 'b) sequence -> ('a, 'b) t
(** {2 Functorial interface} *)
@@ -113,9 +116,9 @@ module type S = sig
val choose : 'a t -> (key * 'a)
(** Some binding, or raises Not_found *)
- val to_seq : 'a t -> (key * 'a) CCSequence.t
+ val to_seq : 'a t -> (key * 'a) sequence
- val of_seq : 'a t -> (key * 'a) CCSequence.t -> 'a t
+ val of_seq : 'a t -> (key * 'a) sequence -> 'a t
end
module type ORDERED = sig
diff --git a/misc/splayTree.ml b/src/misc/splayTree.ml
similarity index 100%
rename from misc/splayTree.ml
rename to src/misc/splayTree.ml
diff --git a/misc/splayTree.mli b/src/misc/splayTree.mli
similarity index 100%
rename from misc/splayTree.mli
rename to src/misc/splayTree.mli
diff --git a/misc/tTree.ml b/src/misc/tTree.ml
similarity index 100%
rename from misc/tTree.ml
rename to src/misc/tTree.ml
diff --git a/misc/tTree.mli b/src/misc/tTree.mli
similarity index 100%
rename from misc/tTree.mli
rename to src/misc/tTree.mli
diff --git a/misc/ty.ml b/src/misc/ty.ml
similarity index 100%
rename from misc/ty.ml
rename to src/misc/ty.ml
diff --git a/misc/ty.mli b/src/misc/ty.mli
similarity index 100%
rename from misc/ty.mli
rename to src/misc/ty.mli
diff --git a/misc/unionFind.ml b/src/misc/unionFind.ml
similarity index 100%
rename from misc/unionFind.ml
rename to src/misc/unionFind.ml
diff --git a/misc/unionFind.mli b/src/misc/unionFind.mli
similarity index 100%
rename from misc/unionFind.mli
rename to src/misc/unionFind.mli
diff --git a/misc/univ.ml b/src/misc/univ.ml
similarity index 100%
rename from misc/univ.ml
rename to src/misc/univ.ml
diff --git a/misc/univ.mli b/src/misc/univ.mli
similarity index 100%
rename from misc/univ.mli
rename to src/misc/univ.mli
diff --git a/misc/utils.ml b/src/misc/utils.ml
similarity index 100%
rename from misc/utils.ml
rename to src/misc/utils.ml
diff --git a/pervasives/CCPervasives.ml b/src/pervasives/CCPervasives.ml
similarity index 100%
rename from pervasives/CCPervasives.ml
rename to src/pervasives/CCPervasives.ml
diff --git a/src/pervasives/containers_pervasives.mldylib b/src/pervasives/containers_pervasives.mldylib
new file mode 100644
index 00000000..9dc3b5e4
--- /dev/null
+++ b/src/pervasives/containers_pervasives.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: ea286cccf88f4c81c7b4627216807d4e)
+CCPervasives
+# OASIS_STOP
diff --git a/src/pervasives/containers_pervasives.mllib b/src/pervasives/containers_pervasives.mllib
new file mode 100644
index 00000000..9dc3b5e4
--- /dev/null
+++ b/src/pervasives/containers_pervasives.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: ea286cccf88f4c81c7b4627216807d4e)
+CCPervasives
+# OASIS_STOP
diff --git a/src/sexp/CCSexp.ml b/src/sexp/CCSexp.ml
new file mode 100644
index 00000000..2387356e
--- /dev/null
+++ b/src/sexp/CCSexp.ml
@@ -0,0 +1,173 @@
+(*
+Copyright (c) 2013, Simon Cruanes
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. Redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*)
+
+(** {1 Simple S-expression parsing/printing} *)
+
+type t = [
+ | `Atom of string
+ | `List of t list
+ ]
+
+let equal a b = a = b
+
+let compare a b = Pervasives.compare a b
+
+let hash a = Hashtbl.hash a
+
+let of_int x = `Atom (string_of_int x)
+let of_float x = `Atom (string_of_float x)
+let of_bool x = `Atom (string_of_bool x)
+let atom x = `Atom x
+let of_unit = `List []
+let of_list l = `List l
+let of_rev_list l = `List (List.rev l)
+let of_pair (x,y) = `List[x;y]
+let of_triple (x,y,z) = `List[x;y;z]
+let of_quad (x,y,z,u) = `List[x;y;z;u]
+
+let of_variant name args = `List (`Atom name :: args)
+let of_field name t = `List [`Atom name; t]
+let of_record l =
+ `List (List.map (fun (n,x) -> of_field n x) l)
+
+(** {6 Traversal of S-exp} *)
+
+module Traverse = struct
+ type 'a conv = t -> 'a option
+
+ let return x = Some x
+
+ let (>|=) e f = match e with
+ | None -> None
+ | Some x -> Some (f x)
+
+ let (>>=) e f = match e with
+ | None -> None
+ | Some x -> f x
+
+ let map_opt f l =
+ let rec recurse acc l = match l with
+ | [] -> Some (List.rev acc)
+ | x::l' ->
+ match f x with
+ | None -> None
+ | Some y -> recurse (y::acc) l'
+ in recurse [] l
+
+ let rec _list_any f l = match l with
+ | [] -> None
+ | x::tl ->
+ match f x with
+ | Some _ as res -> res
+ | None -> _list_any f tl
+
+ let list_any f e = match e with
+ | `Atom _ -> None
+ | `List l -> _list_any f l
+
+ let rec _list_all f acc l = match l with
+ | [] -> List.rev acc
+ | x::tl ->
+ match f x with
+ | Some y -> _list_all f (y::acc) tl
+ | None -> _list_all f acc tl
+
+ let list_all f e = match e with
+ | `Atom _ -> []
+ | `List l -> _list_all f [] l
+
+ let _try_atom e f = match e with
+ | `List _ -> None
+ | `Atom x -> try Some (f x) with _ -> None
+
+ let to_int e = _try_atom e int_of_string
+ let to_bool e = _try_atom e bool_of_string
+ let to_float e = _try_atom e float_of_string
+ let to_string e = _try_atom e (fun x->x)
+
+ let to_pair e = match e with
+ | `List [x;y] -> Some (x,y)
+ | _ -> None
+
+ let to_pair_with f1 f2 e =
+ to_pair e >>= fun (x,y) ->
+ f1 x >>= fun x ->
+ f2 y >>= fun y ->
+ return (x,y)
+
+ let to_triple e = match e with
+ | `List [x;y;z] -> Some (x,y,z)
+ | _ -> None
+
+ let to_triple_with f1 f2 f3 e =
+ to_triple e >>= fun (x,y,z) ->
+ f1 x >>= fun x ->
+ f2 y >>= fun y ->
+ f3 z >>= fun z ->
+ return (x,y,z)
+
+ let to_list e = match e with
+ | `List l -> Some l
+ | `Atom _ -> None
+
+ let to_list_with f (e:t) = match e with
+ | `List l -> map_opt f l
+ | `Atom _ -> None
+
+ let rec _get_field name l = match l with
+ | `List [`Atom n; x] :: _ when name=n -> Some x
+ | _ :: tl -> _get_field name tl
+ | [] -> None
+
+ let get_field name e = match e with
+ | `List l -> _get_field name l
+ | `Atom _ -> None
+
+ let field name f e =
+ get_field name e >>= f
+
+ let rec _get_field_list name l = match l with
+ | `List (`Atom n :: tl) :: _ when name=n -> Some tl
+ | _ :: tl -> _get_field_list name tl
+ | [] -> None
+
+ let field_list name f e = match e with
+ | `List l -> _get_field_list name l >>= f
+ | `Atom _ -> None
+
+ let rec _get_variant s args l = match l with
+ | [] -> None
+ | (s', f) :: _ when s=s' -> f args
+ | _ :: tl -> _get_variant s args tl
+
+ let get_variant l e = match e with
+ | `List (`Atom s :: args) -> _get_variant s args l
+ | `List _ -> None
+ | `Atom s -> _get_variant s [] l
+
+ let get_exn e = match e with
+ | None -> failwith "Sexp.Traverse.get_exn"
+ | Some x -> x
+end
diff --git a/src/sexp/CCSexp.mli b/src/sexp/CCSexp.mli
new file mode 100644
index 00000000..17acdf7b
--- /dev/null
+++ b/src/sexp/CCSexp.mli
@@ -0,0 +1,168 @@
+(*
+Copyright (c) 2013, Simon Cruanes
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. Redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*)
+
+(** {1 Handling S-expressions}
+
+@since 0.4
+
+@since 0.7
+Moved the streaming parser to CCSexpStream
+*)
+
+(** {2 Basics} *)
+
+type t = [
+ | `Atom of string
+ | `List of t list
+ ]
+
+val equal : t -> t -> bool
+val compare : t -> t -> int
+val hash : t -> int
+
+val atom : string -> t (** Build an atom directly from a string *)
+
+val of_int : int -> t
+val of_bool : bool -> t
+val of_list : t list -> t
+val of_rev_list : t list -> t (** Reverse the list *)
+val of_float : float -> t
+val of_unit : t
+val of_pair : t * t -> t
+val of_triple : t * t * t -> t
+val of_quad : t * t * t * t -> t
+
+val of_variant : string -> t list -> t
+(** [of_variant name args] is used to encode algebraic variants
+ into a S-expr. For instance [of_variant "some" [of_int 1]]
+ represents the value [Some 1] *)
+
+val of_field : string -> t -> t
+(** Used to represent one record field *)
+
+val of_record : (string * t) list -> t
+(** Represent a record by its named fields *)
+
+(** {6 Traversal of S-exp}
+
+Example: serializing 2D points
+{[
+type pt = {x:int; y:int };;
+
+let pt_of_sexp e =
+ Sexp.Traverse.(
+ field "x" to_int e >>= fun x ->
+ field "y" to_int e >>= fun y ->
+ return {x;y}
+ );;
+
+let sexp_of_pt pt = Sexp.(of_record ["x", of_int pt.x; "y", of_int pt.y]);;
+
+let l = [{x=1;y=1}; {x=2;y=10}];;
+
+let sexp = Sexp.(of_list (List.map sexp_of_pt l));;
+
+Sexp.Traverse.list_all pt_of_sexp sexp;;
+]}
+
+*)
+
+module Traverse : sig
+ type 'a conv = t -> 'a option
+ (** A converter from S-expressions to 'a is a function [sexp -> 'a option].
+ @since 0.4.1 *)
+
+ val map_opt : ('a -> 'b option) -> 'a list -> 'b list option
+ (** Map over a list, failing as soon as the function fails on any element
+ @since 0.4.1 *)
+
+ val list_any : 'a conv -> t -> 'a option
+ (** [list_any f (List l)] tries [f x] for every element [x] in [List l],
+ and returns the first non-None result (if any). *)
+
+ val list_all : 'a conv -> t -> 'a list
+ (** [list_all f (List l)] returns the list of all [y] such that [x] in [l]
+ and [f x = Some y] *)
+
+ val to_int : int conv
+ (** Expect an integer *)
+
+ val to_string : string conv
+ (** Expect a string (an atom) *)
+
+ val to_bool : bool conv
+ (** Expect a boolean *)
+
+ val to_float : float conv
+ (** Expect a float *)
+
+ val to_list : t list conv
+ (** Expect a list *)
+
+ val to_list_with : (t -> 'a option) -> 'a list conv
+ (** Expect a list, applies [f] to all the elements of the list, and succeeds
+ only if [f] succeeded on every element
+ @since 0.4.1 *)
+
+ val to_pair : (t * t) conv
+ (** Expect a list of two elements *)
+
+ val to_pair_with : 'a conv -> 'b conv -> ('a * 'b) conv
+ (** Same as {!to_pair} but applies conversion functions
+ @since 0.4.1 *)
+
+ val to_triple : (t * t * t) conv
+
+ val to_triple_with : 'a conv -> 'b conv -> 'c conv -> ('a * 'b * 'c) conv
+ (* @since 0.4.1 *)
+
+ val get_field : string -> t conv
+ (** [get_field name e], when [e = List [(n1,x1); (n2,x2) ... ]], extracts
+ the [xi] such that [name = ni], if it can find it. *)
+
+ val field : string -> 'a conv -> 'a conv
+ (** Enriched version of {!get_field}, with a converter as argument *)
+
+ val get_variant : (string * (t list -> 'a option)) list -> 'a conv
+ (** [get_variant l e] checks whether [e = List (Atom s :: args)], and
+ if some pair of [l] is [s, f]. In this case, it calls [f args]
+ and returns its result, otherwise it returns None. *)
+
+ val field_list : string -> (t list -> 'a option) -> 'a conv
+ (** [field_list name f "(... (name a b c d) ...record)"]
+ will look for a field based on the given [name], and expect it to have a
+ list of arguments dealt with by [f] (here, "a b c d").
+ @since 0.4.1 *)
+
+ val (>>=) : 'a option -> ('a -> 'b option) -> 'b option
+
+ val (>|=) : 'a option -> ('a -> 'b) -> 'b option
+
+ val return : 'a -> 'a option
+
+ val get_exn : 'a option -> 'a
+ (** Unwrap an option, possibly failing.
+ @raise Invalid_argument if the argument is [None] *)
+end
diff --git a/src/sexp/CCSexpM.ml b/src/sexp/CCSexpM.ml
new file mode 100644
index 00000000..a6234a5f
--- /dev/null
+++ b/src/sexp/CCSexpM.ml
@@ -0,0 +1,362 @@
+(*
+Copyright (c) 2013, Simon Cruanes
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. Redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*)
+
+(** {1 Simple S-expression parsing/printing} *)
+
+type 'a or_error = [ `Ok of 'a | `Error of string ]
+type 'a sequence = ('a -> unit) -> unit
+type 'a gen = unit -> 'a option
+
+type t = [
+ | `Atom of string
+ | `List of t list
+ ]
+type sexp = t
+
+let _with_in filename f =
+ let ic = open_in filename in
+ try
+ let x = f ic in
+ close_in ic;
+ x
+ with e ->
+ close_in ic;
+ `Error (Printexc.to_string e)
+
+let _with_out filename f =
+ let oc = open_out filename in
+ try
+ let x = f oc in
+ close_out oc;
+ x
+ with e ->
+ close_out oc;
+ raise e
+
+(** {2 Serialization (encoding)} *)
+
+(* shall we escape the string because of one of its chars? *)
+let _must_escape s =
+ try
+ for i = 0 to String.length s - 1 do
+ let c = String.unsafe_get s i in
+ match c with
+ | ' ' | ';' | ')' | '(' | '"' | '\n' | '\t' -> raise Exit
+ | _ when Char.code c > 127 -> raise Exit (* non-ascii *)
+ | _ -> ()
+ done;
+ false
+ with Exit -> true
+
+let rec to_buf b t = match t with
+ | `Atom s when _must_escape s -> Printf.bprintf b "\"%s\"" (String.escaped s)
+ | `Atom s -> Buffer.add_string b s
+ | `List [] -> Buffer.add_string b "()"
+ | `List [x] -> Printf.bprintf b "(%a)" to_buf x
+ | `List l ->
+ Buffer.add_char b '(';
+ List.iteri
+ (fun i t' -> (if i > 0 then Buffer.add_char b ' '; to_buf b t'))
+ l;
+ Buffer.add_char b ')'
+
+let to_string t =
+ let b = Buffer.create 128 in
+ to_buf b t;
+ Buffer.contents b
+
+let rec print fmt t = match t with
+ | `Atom s when _must_escape s -> Format.fprintf fmt "\"%s\"" (String.escaped s)
+ | `Atom s -> Format.pp_print_string fmt s
+ | `List [] -> Format.pp_print_string fmt "()"
+ | `List [x] -> Format.fprintf fmt "@[(%a)@]" print x
+ | `List l ->
+ Format.open_hovbox 2;
+ Format.pp_print_char fmt '(';
+ List.iteri
+ (fun i t' -> (if i > 0 then Format.fprintf fmt "@ "; print fmt t'))
+ l;
+ Format.pp_print_char fmt ')';
+ Format.close_box ()
+
+let rec print_noindent fmt t = match t with
+ | `Atom s when _must_escape s -> Format.fprintf fmt "\"%s\"" (String.escaped s)
+ | `Atom s -> Format.pp_print_string fmt s
+ | `List [] -> Format.pp_print_string fmt "()"
+ | `List [x] -> Format.fprintf fmt "(%a)" print_noindent x
+ | `List l ->
+ Format.pp_print_char fmt '(';
+ List.iteri
+ (fun i t' -> (if i > 0 then Format.pp_print_char fmt ' '; print_noindent fmt t'))
+ l;
+ Format.pp_print_char fmt ')'
+
+let to_chan oc t =
+ let fmt = Format.formatter_of_out_channel oc in
+ print fmt t;
+ Format.pp_print_flush fmt ()
+
+let to_file_seq filename seq =
+ _with_out filename
+ (fun oc ->
+ seq (fun t -> to_chan oc t; output_char oc '\n')
+ )
+
+let to_file filename t = to_file_seq filename (fun k -> k t)
+
+(** {2 Deserialization (decoding)} *)
+
+module type MONAD = sig
+ type 'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+end
+
+type 'a parse_result = ['a or_error | `End ]
+
+module MakeDecode(M : MONAD) = struct
+ let (>>=) = M.(>>=)
+
+ type t = {
+ buf : Bytes.t;
+ refill : Bytes.t -> int -> int -> int M.t;
+ atom : Buffer.t;
+ mutable i : int; (* offset in [buf] *)
+ mutable len : int; (* how many bytes of [buf] are usable *)
+ mutable line : int;
+ mutable col : int;
+ }
+
+ let make ?(bufsize=1024) refill =
+ let bufsize = min (max bufsize 16) Sys.max_string_length in
+ { buf=Bytes.create bufsize;
+ refill;
+ atom = Buffer.create 32;
+ i=0;
+ len=0;
+ line=1;
+ col=1;
+ }
+
+ let _is_digit c = Char.code '0' <= Char.code c && Char.code c <= Char.code '9'
+ let _digit2i c = Char.code c - Char.code '0'
+
+ (* refill buffer. If it works, call k_succ, otherwise call k_fail *)
+ let _refill t k_succ k_fail =
+ t.refill t.buf 0 (Bytes.length t.buf)
+ >>= fun n ->
+ t.i <- 0;
+ t.len <- n;
+ if n = 0 then k_fail t else k_succ t
+
+ (* get next char, assuming t.i < t.len *)
+ let _get t =
+ assert (t.i < t.len);
+ let c = Bytes.get t.buf t.i in
+ t.i <- t.i + 1;
+ if c = '\n' then (t.col <- 1; t.line <- t.line + 1) else t.col <- t.col + 1;
+ c
+
+ (* return an error *)
+ let _error t msg =
+ let b = Buffer.create 32 in
+ Printf.bprintf b "at %d, %d: " t.line t.col;
+ Printf.kbprintf
+ (fun b ->
+ let msg' = Buffer.contents b in
+ M.return (`Error msg')
+ ) b msg
+
+ let _error_eof t = _error t "unexpected end of input"
+
+ (* The parsers all take a success continuation, and the decoder as
+ last arguments. The continuation is used to minimize the
+ number of calls to [>>=] and take two parameters, the next
+ char (if not consumed), and the returned expression itself *)
+
+ (* read expression *)
+ let rec expr k t =
+ if t.i = t.len then _refill t (expr k) _error_eof
+ else match _get t with
+ | ' ' | '\t' | '\n' -> expr k t
+ | c -> expr_starting_with c k t
+
+ and expr_starting_with c k t = match c with
+ | ' ' | '\t' | '\n' -> assert false
+ | ';' -> skip_comment (fun _ () -> expr k t) t
+ | '(' -> expr_list [] k t
+ | ')' -> _error t "unexpected ')'"
+ | '\\' -> _error t "unexpected '\\'"
+ | '"' -> quoted k t
+ | c ->
+ Buffer.add_char t.atom c;
+ atom k t
+
+ (* parse list *)
+ and expr_list acc k t =
+ if t.i = t.len then _refill t (expr_list acc k) _error_eof
+ else match _get t with
+ | ' ' | '\t' | '\n' -> expr_list acc k t
+ | ')' -> k None (`List (List.rev acc))
+ | c ->
+ expr_starting_with c
+ (fun last e -> match last with
+ | Some '(' -> expr_list [] (fun _ l -> expr_list (l::acc) k t) t
+ | Some ')' -> k None (`List (List.rev (e::acc)))
+ | _ -> expr_list (e::acc) k t
+ ) t
+
+ (* return the current atom (last char: c) *)
+ and _return_atom last k t =
+ let s = Buffer.contents t.atom in
+ Buffer.clear t.atom;
+ k last (`Atom s)
+
+ (* parse atom *)
+ and atom k t =
+ if t.i = t.len then _refill t (atom k) (_return_atom None k)
+ else match _get t with
+ | '\\' -> _error t "unexpected '\\' in non-quoted string"
+ | '"' -> _error t "unexpected '\"' in the middle of an atom"
+ | (' ' | '\n' | '\t' | '(' | ')') as c ->
+ _return_atom (Some c) k t
+ | c ->
+ Buffer.add_char t.atom c;
+ atom k t
+
+ (* quoted string *)
+ and quoted k t =
+ if t.i = t.len then _refill t (quoted k) _error_eof
+ else match _get t with
+ | '\\' ->
+ (* read escaped char and continue *)
+ escaped
+ (fun c ->
+ Buffer.add_char t.atom c;
+ quoted k t
+ ) t
+ | '"' -> _return_atom None k t
+ | c ->
+ Buffer.add_char t.atom c;
+ quoted k t
+
+ (* read escaped char *)
+ and escaped k t =
+ if t.i = t.len then _refill t (escaped k) _error_eof
+ else match _get t with
+ | 'n' -> k '\n'
+ | 't' -> k '\t'
+ | 'r' -> k '\r'
+ | 'b' -> k '\b'
+ | '\\' -> k '\\'
+ | '"' -> k '"'
+ | c when _is_digit c ->
+ read2int (_digit2i c) (fun n -> k (Char.chr n)) t
+ | c -> _error t "unexpected escaped char '%c'" c
+
+ and read2int i k t =
+ if t.i = t.len then _refill t (read2int i k) _error_eof
+ else match _get t with
+ | c when _is_digit c -> read1int (10 * i + _digit2i c) k t
+ | c -> _error t "unexpected char '%c' when reading byte" c
+
+ and read1int i k t =
+ if t.i = t.len then _refill t (read1int i k) _error_eof
+ else match _get t with
+ | c when _is_digit c -> k (10 * i + _digit2i c)
+ | c -> _error t "unexpected char '%c' when reading byte" c
+
+ (* skip until end of line, then call next() *)
+ and skip_comment k t =
+ if t.i = t.len
+ then _refill t (skip_comment k) _error_eof
+ else match _get t with
+ | '\n' -> k None ()
+ | _ -> skip_comment k t
+
+ (* top-level expression *)
+ let rec expr_or_end k t =
+ if t.i = t.len
+ then _refill t (expr_or_end k) (fun _ -> M.return `End)
+ else match _get t with
+ | ' ' | '\t' | '\n' -> expr_or_end k t
+ | c -> expr_starting_with c k t
+
+ (* entry point *)
+ let next t : sexp parse_result M.t =
+ expr_or_end (fun _ x -> M.return (`Ok x)) t
+end
+
+module D = MakeDecode(struct
+ type 'a t = 'a
+ let return x = x
+ let (>>=) x f = f x
+end)
+
+let parse_string s : t or_error =
+ let n = String.length s in
+ let stop = ref false in
+ let refill bytes i _len =
+ if !stop then 0
+ else (stop := true; Bytes.blit_string s 0 bytes i n; n)
+ in
+ let d = D.make ~bufsize:n refill in
+ match D.next d with
+ | `End -> `Error "unexpected end of file"
+ | (`Ok _ | `Error _) as res -> res
+
+(*$T
+ CCError.to_opt (parse_string "(abc d/e/f \"hello \\\" () world\" )") <> None
+ CCError.to_opt (parse_string "(abc ( d e ffff ) \"hello/world\")") <> None
+*)
+
+let parse_chan ?bufsize ic =
+ let d = D.make ?bufsize (input ic) in
+ match D.next d with
+ | `End -> `Error "unexpected end of file"
+ | (`Ok _ | `Error _) as res -> res
+
+let parse_chan_gen ?bufsize ic =
+ let d = D.make ?bufsize (input ic) in
+ fun () ->
+ match D.next d with
+ | `End -> None
+ | `Error _ as e -> Some e
+ | `Ok _ as res -> Some res
+
+let parse_chan_list ?bufsize ic =
+ let d = D.make ?bufsize (input ic) in
+ let rec iter acc = match D.next d with
+ | `End -> `Ok (List.rev acc)
+ | `Ok x -> iter (x::acc)
+ | `Error _ as e -> e
+ in
+ iter []
+
+let parse_file filename =
+ _with_in filename (fun ic -> parse_chan ic)
+
+let parse_file_list filename =
+ _with_in filename (fun ic -> parse_chan_list ic)
diff --git a/src/sexp/CCSexpM.mli b/src/sexp/CCSexpM.mli
new file mode 100644
index 00000000..5507fc20
--- /dev/null
+++ b/src/sexp/CCSexpM.mli
@@ -0,0 +1,106 @@
+(*
+Copyright (c) 2013, Simon Cruanes
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. Redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*)
+
+(** {1 Simple and efficient S-expression parsing/printing}
+
+@since 0.7 *)
+
+type 'a or_error = [ `Ok of 'a | `Error of string ]
+type 'a sequence = ('a -> unit) -> unit
+type 'a gen = unit -> 'a option
+
+(** {2 Basics} *)
+
+type t = [
+ | `Atom of string
+ | `List of t list
+ ]
+type sexp = t
+
+(** {2 Serialization (encoding)} *)
+
+val to_buf : Buffer.t -> t -> unit
+
+val to_string : t -> string
+
+val to_file : string -> t -> unit
+
+val to_file_seq : string -> t sequence -> unit
+(** Print the given sequence of expressions to a file *)
+
+val to_chan : out_channel -> t -> unit
+
+val print : Format.formatter -> t -> unit
+(** Pretty-printer nice on human eyes (including indentation) *)
+
+val print_noindent : Format.formatter -> t -> unit
+(** Raw, direct printing as compact as possible *)
+
+(** {2 Deserialization (decoding)} *)
+
+module type MONAD = sig
+ type 'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+end
+
+type 'a parse_result = ['a or_error | `End ]
+(** A parser of ['a] can return [`Ok x] when it parsed a value,
+ or [`Error e] when a parse error was encountered, or
+ [`End] if the input was empty *)
+
+module MakeDecode(M : MONAD) : sig
+ type t
+ (** Decoder *)
+
+ val make : ?bufsize:int -> (Bytes.t -> int -> int -> int M.t) -> t
+ (** Make a decoder with the given function used to refill an
+ internal buffer. The function might return [0] if the
+ input is exhausted.
+ @param bufsize size of internal buffer *)
+
+ val next : t -> sexp parse_result M.t
+ (** Parse the next S-expression or return an error if the input isn't
+ long enough or isn't a proper S-expression *)
+end
+
+val parse_string : string -> t or_error
+(** Parse a string *)
+
+val parse_chan : ?bufsize:int -> in_channel -> t or_error
+(** Parse a S-expression from the given channel. Can read more data than
+ necessary, so don't use this if you need finer-grained control (e.g.
+ to read something else {b after} the S-exp) *)
+
+val parse_chan_gen : ?bufsize:int -> in_channel -> t or_error gen
+(** Parse a channel into a generator of S-expressions *)
+
+val parse_chan_list : ?bufsize:int -> in_channel -> t list or_error
+
+val parse_file : string -> t or_error
+(** Open the file and read a S-exp from it *)
+
+val parse_file_list : string -> t list or_error
+(** Open the file and read a S-exp from it *)
diff --git a/core/CCSexp.ml b/src/sexp/CCSexpStream.ml
similarity index 80%
rename from core/CCSexp.ml
rename to src/sexp/CCSexpStream.ml
index c446b374..38f25c15 100644
--- a/core/CCSexp.ml
+++ b/src/sexp/CCSexpStream.ml
@@ -23,7 +23,10 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
-(** {1 Simple S-expression parsing/printing} *)
+(** {1 S-expressions Parser}
+
+@since 0.4
+@deprecated consider using {!CCSexpM} *)
type 'a or_error = [ `Ok of 'a | `Error of string ]
type 'a sequence = ('a -> unit) -> unit
@@ -34,28 +37,6 @@ type t = [
| `List of t list
]
-let equal a b = a = b
-
-let compare a b = Pervasives.compare a b
-
-let hash a = Hashtbl.hash a
-
-let of_int x = `Atom (string_of_int x)
-let of_float x = `Atom (string_of_float x)
-let of_bool x = `Atom (string_of_bool x)
-let atom x = `Atom x
-let of_unit = `List []
-let of_list l = `List l
-let of_rev_list l = `List (List.rev l)
-let of_pair (x,y) = `List[x;y]
-let of_triple (x,y,z) = `List[x;y;z]
-let of_quad (x,y,z,u) = `List[x;y;z;u]
-
-let of_variant name args = `List (`Atom name :: args)
-let of_field name t = `List [`Atom name; t]
-let of_record l =
- `List (List.map (fun (n,x) -> of_field n x) l)
-
let _with_in filename f =
let ic = open_in filename in
try
@@ -141,7 +122,7 @@ let to_chan oc t =
let to_file_seq filename seq =
_with_out filename
- (fun oc ->
+ (fun oc ->
seq (fun t -> to_chan oc t; output_char oc '\n')
)
@@ -167,7 +148,7 @@ module Source = struct
mutable stop : bool;
buf : Buffer.t; (* accessible chunk of input *)
}
-
+
let make() = {
i = 0;
stop = false;
@@ -231,7 +212,7 @@ module Source = struct
then (
match g() with
| None -> stop := true; NC_end
- | Some buf -> s := buf; i := 0; next ()
+ | Some buf -> s := buf; i := 0; next ()
) else (
let c = String.get !s !i in
incr i;
@@ -580,122 +561,3 @@ module L = struct
| StopNaow -> `Ok (List.rev !l)
end
-(** {6 Traversal of S-exp} *)
-
-module Traverse = struct
- type 'a conv = t -> 'a option
-
- let return x = Some x
-
- let (>|=) e f = match e with
- | None -> None
- | Some x -> Some (f x)
-
- let (>>=) e f = match e with
- | None -> None
- | Some x -> f x
-
- let map_opt f l =
- let rec recurse acc l = match l with
- | [] -> Some (List.rev acc)
- | x::l' ->
- match f x with
- | None -> None
- | Some y -> recurse (y::acc) l'
- in recurse [] l
-
- let rec _list_any f l = match l with
- | [] -> None
- | x::tl ->
- match f x with
- | Some _ as res -> res
- | None -> _list_any f tl
-
- let list_any f e = match e with
- | `Atom _ -> None
- | `List l -> _list_any f l
-
- let rec _list_all f acc l = match l with
- | [] -> List.rev acc
- | x::tl ->
- match f x with
- | Some y -> _list_all f (y::acc) tl
- | None -> _list_all f acc tl
-
- let list_all f e = match e with
- | `Atom _ -> []
- | `List l -> _list_all f [] l
-
- let _try_atom e f = match e with
- | `List _ -> None
- | `Atom x -> try Some (f x) with _ -> None
-
- let to_int e = _try_atom e int_of_string
- let to_bool e = _try_atom e bool_of_string
- let to_float e = _try_atom e float_of_string
- let to_string e = _try_atom e (fun x->x)
-
- let to_pair e = match e with
- | `List [x;y] -> Some (x,y)
- | _ -> None
-
- let to_pair_with f1 f2 e =
- to_pair e >>= fun (x,y) ->
- f1 x >>= fun x ->
- f2 y >>= fun y ->
- return (x,y)
-
- let to_triple e = match e with
- | `List [x;y;z] -> Some (x,y,z)
- | _ -> None
-
- let to_triple_with f1 f2 f3 e =
- to_triple e >>= fun (x,y,z) ->
- f1 x >>= fun x ->
- f2 y >>= fun y ->
- f3 z >>= fun z ->
- return (x,y,z)
-
- let to_list e = match e with
- | `List l -> Some l
- | `Atom _ -> None
-
- let to_list_with f (e:t) = match e with
- | `List l -> map_opt f l
- | `Atom _ -> None
-
- let rec _get_field name l = match l with
- | `List [`Atom n; x] :: _ when name=n -> Some x
- | _ :: tl -> _get_field name tl
- | [] -> None
-
- let get_field name e = match e with
- | `List l -> _get_field name l
- | `Atom _ -> None
-
- let field name f e =
- get_field name e >>= f
-
- let rec _get_field_list name l = match l with
- | `List (`Atom n :: tl) :: _ when name=n -> Some tl
- | _ :: tl -> _get_field_list name tl
- | [] -> None
-
- let field_list name f e = match e with
- | `List l -> _get_field_list name l >>= f
- | `Atom _ -> None
-
- let rec _get_variant s args l = match l with
- | [] -> None
- | (s', f) :: _ when s=s' -> f args
- | _ :: tl -> _get_variant s args tl
-
- let get_variant l e = match e with
- | `List (`Atom s :: args) -> _get_variant s args l
- | `List _ -> None
- | `Atom s -> _get_variant s [] l
-
- let get_exn e = match e with
- | None -> failwith "Sexp.Traverse.get_exn"
- | Some x -> x
-end
diff --git a/core/CCSexp.mli b/src/sexp/CCSexpStream.mli
similarity index 59%
rename from core/CCSexp.mli
rename to src/sexp/CCSexpStream.mli
index 09de18e6..9fecedac 100644
--- a/core/CCSexp.mli
+++ b/src/sexp/CCSexpStream.mli
@@ -23,48 +23,20 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
-(** {1 Simple and efficient S-expression parsing/printing}
+(** {1 S-expressions Parser}
-@since 0.4 *)
+@since 0.4
+@deprecated consider using {!CCSexpM} *)
type 'a or_error = [ `Ok of 'a | `Error of string ]
type 'a sequence = ('a -> unit) -> unit
type 'a gen = unit -> 'a option
-(** {2 Basics} *)
-
type t = [
| `Atom of string
| `List of t list
]
-val equal : t -> t -> bool
-val compare : t -> t -> int
-val hash : t -> int
-
-val atom : string -> t (** Build an atom directly from a string *)
-
-val of_int : int -> t
-val of_bool : bool -> t
-val of_list : t list -> t
-val of_rev_list : t list -> t (** Reverse the list *)
-val of_float : float -> t
-val of_unit : t
-val of_pair : t * t -> t
-val of_triple : t * t * t -> t
-val of_quad : t * t * t * t -> t
-
-val of_variant : string -> t list -> t
-(** [of_variant name args] is used to encode algebraic variants
- into a S-expr. For instance [of_variant "some" [of_int 1]]
- represents the value [Some 1] *)
-
-val of_field : string -> t -> t
-(** Used to represent one record field *)
-
-val of_record : (string * t) list -> t
-(** Represent a record by its named fields *)
-
(** {2 Serialization (encoding)} *)
val to_buf : Buffer.t -> t -> unit
@@ -225,104 +197,3 @@ module L : sig
val of_seq : string sequence -> t list or_error
end
-(** {6 Traversal of S-exp}
-
-Example: serializing 2D points
-{[
-type pt = {x:int; y:int };;
-
-let pt_of_sexp e =
- Sexp.Traverse.(
- field "x" to_int e >>= fun x ->
- field "y" to_int e >>= fun y ->
- return {x;y}
- );;
-
-let sexp_of_pt pt = Sexp.(of_record ["x", of_int pt.x; "y", of_int pt.y]);;
-
-let l = [{x=1;y=1}; {x=2;y=10}];;
-
-let sexp = Sexp.(of_list (List.map sexp_of_pt l));;
-
-Sexp.Traverse.list_all pt_of_sexp sexp;;
-]}
-
-*)
-
-module Traverse : sig
- type 'a conv = t -> 'a option
- (** A converter from S-expressions to 'a is a function [sexp -> 'a option].
- @since 0.4.1 *)
-
- val map_opt : ('a -> 'b option) -> 'a list -> 'b list option
- (** Map over a list, failing as soon as the function fails on any element
- @since 0.4.1 *)
-
- val list_any : 'a conv -> t -> 'a option
- (** [list_any f (List l)] tries [f x] for every element [x] in [List l],
- and returns the first non-None result (if any). *)
-
- val list_all : 'a conv -> t -> 'a list
- (** [list_all f (List l)] returns the list of all [y] such that [x] in [l]
- and [f x = Some y] *)
-
- val to_int : int conv
- (** Expect an integer *)
-
- val to_string : string conv
- (** Expect a string (an atom) *)
-
- val to_bool : bool conv
- (** Expect a boolean *)
-
- val to_float : float conv
- (** Expect a float *)
-
- val to_list : t list conv
- (** Expect a list *)
-
- val to_list_with : (t -> 'a option) -> 'a list conv
- (** Expect a list, applies [f] to all the elements of the list, and succeeds
- only if [f] succeeded on every element
- @since 0.4.1 *)
-
- val to_pair : (t * t) conv
- (** Expect a list of two elements *)
-
- val to_pair_with : 'a conv -> 'b conv -> ('a * 'b) conv
- (** Same as {!to_pair} but applies conversion functions
- @since 0.4.1 *)
-
- val to_triple : (t * t * t) conv
-
- val to_triple_with : 'a conv -> 'b conv -> 'c conv -> ('a * 'b * 'c) conv
- (* @since 0.4.1 *)
-
- val get_field : string -> t conv
- (** [get_field name e], when [e = List [(n1,x1); (n2,x2) ... ]], extracts
- the [xi] such that [name = ni], if it can find it. *)
-
- val field : string -> 'a conv -> 'a conv
- (** Enriched version of {!get_field}, with a converter as argument *)
-
- val get_variant : (string * (t list -> 'a option)) list -> 'a conv
- (** [get_variant l e] checks whether [e = List (Atom s :: args)], and
- if some pair of [l] is [s, f]. In this case, it calls [f args]
- and returns its result, otherwise it returns None. *)
-
- val field_list : string -> (t list -> 'a option) -> 'a conv
- (** [field_list name f "(... (name a b c d) ...record)"]
- will look for a field based on the given [name], and expect it to have a
- list of arguments dealt with by [f] (here, "a b c d").
- @since 0.4.1 *)
-
- val (>>=) : 'a option -> ('a -> 'b option) -> 'b option
-
- val (>|=) : 'a option -> ('a -> 'b) -> 'b option
-
- val return : 'a -> 'a option
-
- val get_exn : 'a option -> 'a
- (** Unwrap an option, possibly failing.
- @raise Invalid_argument if the argument is [None] *)
-end
diff --git a/src/sexp/containers_sexp.mldylib b/src/sexp/containers_sexp.mldylib
new file mode 100644
index 00000000..d0508313
--- /dev/null
+++ b/src/sexp/containers_sexp.mldylib
@@ -0,0 +1,6 @@
+# OASIS_START
+# DO NOT EDIT (digest: e7d1bfe0f18e27e2b9ff76951f3a9524)
+CCSexp
+CCSexpStream
+CCSexpM
+# OASIS_STOP
diff --git a/src/sexp/containers_sexp.mllib b/src/sexp/containers_sexp.mllib
new file mode 100644
index 00000000..d0508313
--- /dev/null
+++ b/src/sexp/containers_sexp.mllib
@@ -0,0 +1,6 @@
+# OASIS_START
+# DO NOT EDIT (digest: e7d1bfe0f18e27e2b9ff76951f3a9524)
+CCSexp
+CCSexpStream
+CCSexpM
+# OASIS_STOP
diff --git a/string/KMP.ml b/src/string/KMP.ml
similarity index 100%
rename from string/KMP.ml
rename to src/string/KMP.ml
diff --git a/string/KMP.mli b/src/string/KMP.mli
similarity index 100%
rename from string/KMP.mli
rename to src/string/KMP.mli
diff --git a/src/string/containers_string.mldylib b/src/string/containers_string.mldylib
new file mode 100644
index 00000000..48464c54
--- /dev/null
+++ b/src/string/containers_string.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: c89cc456e050edff914368d7fbea4eca)
+Containers_string
+# OASIS_STOP
diff --git a/src/string/containers_string.mllib b/src/string/containers_string.mllib
new file mode 100644
index 00000000..48464c54
--- /dev/null
+++ b/src/string/containers_string.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: c89cc456e050edff914368d7fbea4eca)
+Containers_string
+# OASIS_STOP
diff --git a/src/string/containers_string.mlpack b/src/string/containers_string.mlpack
new file mode 100644
index 00000000..6daaf586
--- /dev/null
+++ b/src/string/containers_string.mlpack
@@ -0,0 +1,5 @@
+# OASIS_START
+# DO NOT EDIT (digest: eed887f169b0c8e02f98f97c676f846c)
+KMP
+Levenshtein
+# OASIS_STOP
diff --git a/string/levenshtein.ml b/src/string/levenshtein.ml
similarity index 100%
rename from string/levenshtein.ml
rename to src/string/levenshtein.ml
diff --git a/string/levenshtein.mli b/src/string/levenshtein.mli
similarity index 100%
rename from string/levenshtein.mli
rename to src/string/levenshtein.mli
diff --git a/threads/CCFuture.ml b/src/threads/CCFuture.ml
similarity index 100%
rename from threads/CCFuture.ml
rename to src/threads/CCFuture.ml
diff --git a/threads/CCFuture.mli b/src/threads/CCFuture.mli
similarity index 100%
rename from threads/CCFuture.mli
rename to src/threads/CCFuture.mli
diff --git a/src/threads/containers_thread.mldylib b/src/threads/containers_thread.mldylib
new file mode 100644
index 00000000..420c8b75
--- /dev/null
+++ b/src/threads/containers_thread.mldylib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: ede75f11c3857d71e591f7b889f4d09d)
+CCFuture
+# OASIS_STOP
diff --git a/src/threads/containers_thread.mllib b/src/threads/containers_thread.mllib
new file mode 100644
index 00000000..420c8b75
--- /dev/null
+++ b/src/threads/containers_thread.mllib
@@ -0,0 +1,4 @@
+# OASIS_START
+# DO NOT EDIT (digest: ede75f11c3857d71e591f7b889f4d09d)
+CCFuture
+# OASIS_STOP
diff --git a/tests/lwt/test_Behavior.ml b/tests/lwt/test_Behavior.ml
deleted file mode 100644
index 7830655d..00000000
--- a/tests/lwt/test_Behavior.ml
+++ /dev/null
@@ -1,79 +0,0 @@
-
-open OUnit
-
-module B = Behavior
-
-let lwt_get fut = match Lwt.state fut with
- | Lwt.Sleep
- | Lwt.Fail _ -> None
- | Lwt.Return x -> Some x
-
-let test_do () =
- let r = ref false in
- let t = B.do_succeed (fun () -> r := true) in
- let res = B.run t in
- OUnit.assert_equal true !r;
- OUnit.assert_equal (Some true) (lwt_get res);
- ()
-
-let test_seq () =
- let l = ref [] in
- (* add int to [l] *)
- let add x = l := x :: !l in
- let t = B.sequence
- [ B.do_ (fun () -> add 3; true);
- B.do_ (fun () -> add 2; true);
- B.test (fun () -> List.length !l = 2);
- B.do_ (fun () -> add 1; true);
- ] in
- let res = B.run t in
- OUnit.assert_equal [1;2;3] !l;
- OUnit.assert_equal (Some true) (lwt_get res);
- ()
-
-let test_wait () =
- let e, send_e = Lwt.wait () in
- let t = B.run (B.sequence [B.wait_ e; B.succeed]) in
- OUnit.assert_equal None (lwt_get t);
- Lwt.wakeup send_e ();
- OUnit.assert_equal (Some true) (lwt_get t);
- ()
-
-let test_parallel () =
- (* forall fails *)
- let e, send_e = Lwt.wait () in
- let t =
- B.parallel ~strat:B.PSForall
- [ B.sequence [B.wait_ e; B.succeed];
- B.fail
- ] in
- let t = B.run t in
- let res = Lwt_main.run
- (let open Lwt in
- choose [t; Lwt_unix.sleep 0.1 >>= fun () -> (Lwt.wakeup send_e (); return true)])
- in
- OUnit.assert_equal false res;
- (* exists succeeds *)
- let e, send_e = Lwt.wait () in
- let t =
- B.parallel ~strat:B.PSExists
- [ B.sequence [B.wait_ e; B.succeed];
- B.fail
- ] in
- let t = B.run t in
- let res = Lwt_main.run
- (let open Lwt in
- choose [t; Lwt_unix.sleep 0.1 >>= fun () -> (Lwt.wakeup send_e ();
- Lwt_unix.sleep 0.1 >>= (fun () -> return true))])
- in
- OUnit.assert_equal true res;
- ()
-
-
-let suite =
- "test_behavior" >:::
- [ "test_do" >:: test_do;
- "test_seq" >:: test_seq;
- "test_wait" >:: test_wait;
- "test_parallel" >:: test_parallel;
- ]
diff --git a/tests/run_tests.ml b/tests/run_tests.ml
index cf4787ac..2641584d 100644
--- a/tests/run_tests.ml
+++ b/tests/run_tests.ml
@@ -13,7 +13,6 @@ let suite =
Test_cc.suite;
Test_puf.suite;
Test_vector.suite;
- Test_gen.suite;
Test_deque.suite;
Test_fHashtbl.suite;
Test_fQueue.suite;
diff --git a/tests/test_CCHeap.ml b/tests/test_CCHeap.ml
index a0c97a79..3b4547a3 100644
--- a/tests/test_CCHeap.ml
+++ b/tests/test_CCHeap.ml
@@ -3,8 +3,6 @@
open OUnit
-module Sequence = CCSequence
-
module H = CCHeap.Make(struct type t = int let leq x y =x<=y end)
let empty = H.empty
diff --git a/tests/test_PersistentHashtbl.ml b/tests/test_PersistentHashtbl.ml
index 8d466484..dd84be8a 100644
--- a/tests/test_PersistentHashtbl.ml
+++ b/tests/test_PersistentHashtbl.ml
@@ -2,7 +2,6 @@
open OUnit
module H = CCPersistentHashtbl.Make(CCInt)
-module Sequence = CCSequence
let test_add () =
let h = H.create 32 in
diff --git a/tests/test_bv.ml b/tests/test_bv.ml
index d6909679..2a7a6152 100644
--- a/tests/test_bv.ml
+++ b/tests/test_bv.ml
@@ -1,6 +1,6 @@
open OUnit
-module Sequence = CCSequence
+
let test_cardinal () =
let bv1 = CCBV.create ~size:87 true in
diff --git a/tests/test_deque.ml b/tests/test_deque.ml
index aecd15d1..76a5448a 100644
--- a/tests/test_deque.ml
+++ b/tests/test_deque.ml
@@ -2,7 +2,7 @@
open OUnit
module Deque = CCDeque
-module Sequence = CCSequence
+
let plist l = CCPrint.to_string (CCList.pp CCInt.pp) l
let pint i = string_of_int i
diff --git a/tests/test_fHashtbl.ml b/tests/test_fHashtbl.ml
index 1c81e37e..d77d7b13 100644
--- a/tests/test_fHashtbl.ml
+++ b/tests/test_fHashtbl.ml
@@ -2,7 +2,7 @@
open OUnit
open Containers_misc
-module Sequence = CCSequence
+
module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct
let test_add () =
diff --git a/tests/test_fQueue.ml b/tests/test_fQueue.ml
index 33082e5e..7388d551 100644
--- a/tests/test_fQueue.ml
+++ b/tests/test_fQueue.ml
@@ -2,7 +2,7 @@
open OUnit
module FQueue = CCFQueue
-module Sequence = CCSequence
+
let test_empty () =
let q = FQueue.empty in
diff --git a/tests/test_flatHashtbl.ml b/tests/test_flatHashtbl.ml
index 60437386..d0cde3a9 100644
--- a/tests/test_flatHashtbl.ml
+++ b/tests/test_flatHashtbl.ml
@@ -2,7 +2,7 @@
open OUnit
open Containers_misc
-module Sequence = CCSequence
+
module IHashtbl = FlatHashtbl.Make(struct
type t = int
diff --git a/tests/test_gen.ml b/tests/test_gen.ml
deleted file mode 100644
index 17596130..00000000
--- a/tests/test_gen.ml
+++ /dev/null
@@ -1,132 +0,0 @@
-
-open OUnit
-open CCFun
-
-module Gen = CCGen
-module GR = Gen.Restart
-
-let pint i = string_of_int i
-let plist l =
- CCPrint.to_string (CCList.pp CCInt.pp) l
-let pstrlist l =
- CCPrint.to_string (CCList.pp Buffer.add_string) l
-
-let test_singleton () =
- let gen = Gen.singleton 42 in
- OUnit.assert_equal (Some 42) (Gen.get gen);
- OUnit.assert_equal None (Gen.get gen);
- let gen = Gen.singleton 42 in
- OUnit.assert_equal 1 (Gen.length gen);
- ()
-
-let test_iter () =
- let e = GR.(1 -- 10) in
- OUnit.assert_equal ~printer:pint 10 (GR.length e);
- OUnit.assert_equal [1;2] GR.(to_list (1 -- 2));
- OUnit.assert_equal [1;2;3;4;5] (GR.to_list (GR.take 5 e));
- ()
-
-let test_map () =
- let e = Gen.(1 -- 10) in
- let e' = Gen.map string_of_int e in
- OUnit.assert_equal ~printer:pstrlist ["9"; "10"] (Gen.to_list (Gen.drop 8 e'));
- ()
-
-let test_append () =
- let e = Gen.append Gen.(1 -- 5) Gen.(6 -- 10) in
- OUnit.assert_equal [10;9;8;7;6;5;4;3;2;1] (Gen.to_rev_list e);
- ()
-
-let test_flatMap () =
- let e = Gen.(1 -- 3) in
- let e' = Gen.(e >>= (fun x -> x -- (x+1))) in
- OUnit.assert_equal [1;2;2;3;3;4] (Gen.to_list e');
- ()
-
-let test_zip () =
- let e = Gen.zip_with (+) (Gen.repeat 1) Gen.(4--7) in
- OUnit.assert_equal [5;6;7;8] (Gen.to_list e);
- ()
-
-let test_filterMap () =
- let f x = if x mod 2 = 0 then Some (string_of_int x) else None in
- let e = Gen.filter_map f Gen.(1 -- 10) in
- OUnit.assert_equal ["2"; "4"; "6"; "8"; "10"] (Gen.to_list e);
- ()
-
-let test_merge () =
- let e = Gen.of_list [Gen.(1--3); Gen.(4--6); Gen.(7--9)] in
- let e' = Gen.merge e in
- OUnit.assert_equal [1;2;3;4;5;6;7;8;9] (Gen.to_list e' |> List.sort compare);
- ()
-
-let test_persistent () =
- let i = ref 0 in
- let gen () =
- let j = !i in
- if j > 5 then None else (incr i; Some j)
- in
- let e = Gen.persistent gen in
- OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
- OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
- OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
- ()
-
-let test_round_robin () =
- let e = GR.round_robin ~n:2 GR.(1--10) in
- match e with
- | [a;b] ->
- OUnit.assert_equal [1;3;5;7;9] (Gen.to_list a);
- OUnit.assert_equal [2;4;6;8;10] (Gen.to_list b)
- | _ -> OUnit.assert_failure "wrong list lenght"
-
-let test_big_rr () =
- let e = GR.round_robin ~n:3 GR.(1 -- 999) in
- let l = List.map Gen.length e in
- OUnit.assert_equal [333;333;333] l;
- ()
-
-let test_merge_sorted () =
- [Gen.of_list [1;3;5]; Gen.of_list [0;1;1;3;4;6;10]; Gen.of_list [2;2;11]]
- |> Gen.sorted_merge_n ?cmp:None
- |> Gen.to_list
- |> OUnit.assert_equal ~printer:Helpers.print_int_list [0;1;1;1;2;2;3;3;4;5;6;10;11]
-
-let test_interleave () =
- let e1 = Gen.of_list [1;3;5;7;9] in
- let e2 = Gen.of_list [2;4;6;8;10] in
- let e = Gen.interleave e1 e2 in
- OUnit.assert_equal [1;2;3;4;5;6;7;8;9;10] (Gen.to_list e);
- ()
-
-let test_intersperse () =
- let e = Gen.(1 -- 5) in
- let e' = Gen.intersperse 0 e in
- OUnit.assert_equal [1;0;2;0;3;0;4;0;5] (Gen.to_list e');
- ()
-
-let test_product () =
- let printer = Helpers.print_int_int_list in
- let e = Gen.product Gen.(1--3) Gen.(4--5) in
- OUnit.assert_equal ~printer [1,4; 1,5; 2,4; 2,5; 3,4; 3,5]
- (List.sort compare (Gen.to_list e));
- ()
-
-let suite =
- "test_gen" >:::
- [ "test_singleton" >:: test_singleton;
- "test_iter" >:: test_iter;
- "test_map" >:: test_map;
- "test_append" >:: test_append;
- "test_flatMap" >:: test_flatMap;
- "test_zip" >:: test_zip;
- "test_filterMap" >:: test_filterMap;
- "test_merge" >:: test_merge;
- "test_persistent" >:: test_persistent;
- "test_round_robin" >:: test_round_robin;
- "test_big_rr" >:: test_big_rr;
- "test_merge_sorted" >:: test_merge_sorted;
- "test_interleave" >:: test_interleave;
- "test_intersperse" >:: test_intersperse;
- "test_product" >:: test_product;
- ]
diff --git a/tests/test_graph.ml b/tests/test_graph.ml
index a18913a7..70e126d3 100644
--- a/tests/test_graph.ml
+++ b/tests/test_graph.ml
@@ -5,7 +5,7 @@ open OUnit
open Helpers
open Containers_misc
-module Sequence = CCSequence
+
module G = PersistentGraph
(* build a graph from a list of pairs of ints *)
diff --git a/tests/test_heap.ml b/tests/test_heap.ml
index c4162e23..62b62586 100644
--- a/tests/test_heap.ml
+++ b/tests/test_heap.ml
@@ -3,7 +3,7 @@
open OUnit
open Helpers
open Containers_misc
-module Sequence = CCSequence
+
let test_empty () =
let h = Heap.empty ~cmp:(fun x y -> x - y) in
diff --git a/tests/test_mixtbl.ml b/tests/test_mixtbl.ml
index f58fc2bb..2e6ee637 100644
--- a/tests/test_mixtbl.ml
+++ b/tests/test_mixtbl.ml
@@ -3,6 +3,8 @@ open OUnit
open Containers_misc
open CCFun
+module Mixtbl = CCMixtbl
+
let example () =
let inj_int = Mixtbl.create_inj () in
let tbl = Mixtbl.create 10 in
@@ -66,7 +68,7 @@ let test_keys () =
Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
- let l = Mixtbl.keys_seq tbl |> CCSequence.to_list in
+ let l = Mixtbl.keys_seq tbl |> Sequence.to_list in
OUnit.assert_equal ["baaz"; "bar"; "foo"] (List.sort compare l);
()
@@ -78,9 +80,9 @@ let test_bindings () =
Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
Mixtbl.set ~inj:inj_str tbl "str" "rts";
- let l_int = Mixtbl.bindings_of tbl ~inj:inj_int |> CCSequence.to_list in
+ let l_int = Mixtbl.bindings_of tbl ~inj:inj_int |> Sequence.to_list in
OUnit.assert_equal ["bar", 2; "foo", 1] (List.sort compare l_int);
- let l_str = Mixtbl.bindings_of tbl ~inj:inj_str |> CCSequence.to_list in
+ let l_str = Mixtbl.bindings_of tbl ~inj:inj_str |> Sequence.to_list in
OUnit.assert_equal ["baaz", "hello"; "str", "rts"] (List.sort compare l_str);
()
diff --git a/tests/test_pHashtbl.ml b/tests/test_pHashtbl.ml
index ce663ecd..c00f0d27 100644
--- a/tests/test_pHashtbl.ml
+++ b/tests/test_pHashtbl.ml
@@ -2,7 +2,7 @@
open OUnit
open Containers_misc
-module Sequence = CCSequence
+
let test_add () =
let h = PHashtbl.create 5 in
diff --git a/tests/test_splayMap.ml b/tests/test_splayMap.ml
index aa22a5a1..fb1d85b8 100644
--- a/tests/test_splayMap.ml
+++ b/tests/test_splayMap.ml
@@ -2,7 +2,7 @@
open OUnit
open Containers_misc
-module Sequence = CCSequence
+
let test1 () =
let empty = SplayMap.empty () in
diff --git a/tests/test_vector.ml b/tests/test_vector.ml
index 878937a4..c8ece7c6 100644
--- a/tests/test_vector.ml
+++ b/tests/test_vector.ml
@@ -2,7 +2,7 @@
open OUnit
module Vector = CCVector
-module Sequence = CCSequence
+
let test_clear () =
let v = Vector.of_seq Sequence.(1 -- 10) in
diff --git a/tests/threads/test_future.ml b/tests/threads/test_future.ml
index 4c7bdf18..cabb7f39 100644
--- a/tests/threads/test_future.ml
+++ b/tests/threads/test_future.ml
@@ -15,9 +15,9 @@ let test_mvar () =
()
let test_parallel () =
- let l = CCSequence.(1 -- 300) in
- let l = CCSequence.map (fun _ -> Future.spawn (fun () -> Thread.delay 0.1; 1)) l in
- let l = CCSequence.to_list l in
+ let l = Sequence.(1 -- 300) in
+ let l = Sequence.map (fun _ -> Future.spawn (fun () -> Thread.delay 0.1; 1)) l in
+ let l = Sequence.to_list l in
let l' = List.map Future.get l in
OUnit.assert_equal 300 (List.fold_left (+) 0 l');
()