This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
523
unikernel/duniverse/dune_/vendor/re/LICENSE.md
vendored
Normal file
523
unikernel/duniverse/dune_/vendor/re/LICENSE.md
vendored
Normal file
|
|
@ -0,0 +1,523 @@
|
|||
This Software is distributed under the terms of the GNU Lesser
|
||||
General Public License version 2.1 (included below), or (at your
|
||||
option) any later version.
|
||||
|
||||
As a special exception to the GNU Library General Public License, you
|
||||
may link, statically or dynamically, a "work that uses the Library"
|
||||
with a publicly distributed version of the Library to produce an
|
||||
executable file containing portions of the Library, and distribute
|
||||
that executable file under terms of your choice, without any of the
|
||||
additional requirements listed in clause 6 of the GNU Library General
|
||||
Public License. By "a publicly distributed version of the Library",
|
||||
we mean either the unmodified Library, or a modified version of the
|
||||
Library that is distributed under the conditions defined in clause 3
|
||||
of the GNU Library General Public License. This exception does not
|
||||
however invalidate any other reasons why the executable file might be
|
||||
covered by the GNU Library General Public License.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 of the License, or (at your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
673
unikernel/duniverse/dune_/vendor/re/src/automata.ml
vendored
Normal file
673
unikernel/duniverse/dune_/vendor/re/src/automata.ml
vendored
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
type sem = [ `Longest | `Shortest | `First ]
|
||||
|
||||
type rep_kind = [ `Greedy | `Non_greedy ]
|
||||
|
||||
type mark = int
|
||||
type idx = int
|
||||
|
||||
type expr = { id : int; def : def }
|
||||
|
||||
and def =
|
||||
Cst of Cset.t
|
||||
| Alt of expr list
|
||||
| Seq of sem * expr * expr
|
||||
| Eps
|
||||
| Rep of rep_kind * sem * expr
|
||||
| Mark of int
|
||||
| Erase of int * int
|
||||
| Before of Category.t
|
||||
| After of Category.t
|
||||
| Pmark of Pmark.t
|
||||
|
||||
let hash_combine h accu = accu * 65599 + h
|
||||
|
||||
module Marks = struct
|
||||
type t =
|
||||
{ marks : (int * int) list
|
||||
; pmarks : Pmark.Set.t }
|
||||
|
||||
let empty = { marks = [] ; pmarks = Pmark.Set.empty }
|
||||
|
||||
let rec merge_marks_offset old = function
|
||||
| [] ->
|
||||
old
|
||||
| (i, v) :: rem ->
|
||||
let nw' = merge_marks_offset (List.remove_assq i old) rem in
|
||||
if v = -2 then
|
||||
nw'
|
||||
else
|
||||
(i, v) :: nw'
|
||||
|
||||
let merge old nw =
|
||||
{ marks = merge_marks_offset old.marks nw.marks
|
||||
; pmarks = Pmark.Set.union old.pmarks nw.pmarks }
|
||||
|
||||
let rec hash_marks_offset l accu =
|
||||
match l with
|
||||
[] -> accu
|
||||
| (a, i) :: r -> hash_marks_offset r (hash_combine a (hash_combine i accu))
|
||||
|
||||
let hash m accu =
|
||||
hash_marks_offset m.marks (hash_combine (Hashtbl.hash m.pmarks) accu)
|
||||
|
||||
let rec marks_set_idx idx = function
|
||||
| (a, -1) :: rem ->
|
||||
(a, idx) :: marks_set_idx idx rem
|
||||
| marks ->
|
||||
marks
|
||||
|
||||
let marks_set_idx marks idx =
|
||||
{ marks with marks = marks_set_idx idx marks.marks }
|
||||
|
||||
let pp_marks ch t =
|
||||
match t.marks with
|
||||
| [] ->
|
||||
()
|
||||
| (a, i) :: r ->
|
||||
Format.fprintf ch "%d-%d" a i;
|
||||
List.iter (fun (a, i) -> Format.fprintf ch " %d-%d" a i) r
|
||||
end
|
||||
|
||||
(****)
|
||||
|
||||
let pp_sem ch k =
|
||||
Format.pp_print_string ch
|
||||
(match k with
|
||||
`Shortest -> "short"
|
||||
| `Longest -> "long"
|
||||
| `First -> "first")
|
||||
|
||||
|
||||
let pp_rep_kind fmt = function
|
||||
| `Greedy -> Format.pp_print_string fmt "Greedy"
|
||||
| `Non_greedy -> Format.pp_print_string fmt "Non_greedy"
|
||||
|
||||
let rec pp ch e =
|
||||
let open Fmt in
|
||||
match e.def with
|
||||
Cst l ->
|
||||
sexp ch "cst" Cset.pp l;
|
||||
| Alt l ->
|
||||
sexp ch "alt" (list pp) l
|
||||
| Seq (k, e, e') ->
|
||||
sexp ch "seq" (triple pp_sem pp pp) (k, e, e')
|
||||
| Eps ->
|
||||
str ch "eps"
|
||||
| Rep (_rk, k, e) ->
|
||||
sexp ch "rep" (pair pp_sem pp) (k, e)
|
||||
| Mark i ->
|
||||
sexp ch "mark" int i
|
||||
| Pmark i ->
|
||||
sexp ch "pmark" int (i :> int)
|
||||
| Erase (b, e) ->
|
||||
sexp ch "erase" (pair int int) (b, e)
|
||||
| Before c ->
|
||||
sexp ch "before" Category.pp c
|
||||
| After c ->
|
||||
sexp ch "after" Category.pp c
|
||||
|
||||
|
||||
(****)
|
||||
|
||||
let rec first f = function
|
||||
| [] ->
|
||||
None
|
||||
| x :: r ->
|
||||
match f x with
|
||||
None -> first f r
|
||||
| Some _ as res -> res
|
||||
|
||||
(****)
|
||||
|
||||
type ids = int ref
|
||||
let create_ids () = ref 0
|
||||
|
||||
let eps_expr = { id = 0; def = Eps }
|
||||
|
||||
let mk_expr ids def =
|
||||
incr ids;
|
||||
{ id = !ids; def = def }
|
||||
|
||||
let empty ids = mk_expr ids (Alt [])
|
||||
|
||||
let cst ids s =
|
||||
if Cset.is_empty s
|
||||
then empty ids
|
||||
else mk_expr ids (Cst s)
|
||||
|
||||
let alt ids = function
|
||||
| [] -> empty ids
|
||||
| [c] -> c
|
||||
| l -> mk_expr ids (Alt l)
|
||||
|
||||
let seq ids kind x y =
|
||||
match x.def, y.def with
|
||||
Alt [], _ -> x
|
||||
| _, Alt [] -> y
|
||||
| Eps, _ -> y
|
||||
| _, Eps when kind = `First -> x
|
||||
| _ -> mk_expr ids (Seq (kind, x, y))
|
||||
|
||||
let is_eps expr =
|
||||
match expr.def with
|
||||
| Eps -> true
|
||||
| _ -> false
|
||||
|
||||
let eps ids = mk_expr ids Eps
|
||||
|
||||
let rep ids kind sem x = mk_expr ids (Rep (kind, sem, x))
|
||||
|
||||
let mark ids m = mk_expr ids (Mark m)
|
||||
|
||||
let pmark ids i = mk_expr ids (Pmark i)
|
||||
|
||||
let erase ids m m' = mk_expr ids (Erase (m, m'))
|
||||
|
||||
let before ids c = mk_expr ids (Before c)
|
||||
|
||||
let after ids c = mk_expr ids (After c)
|
||||
|
||||
(****)
|
||||
|
||||
let rec rename ids x =
|
||||
match x.def with
|
||||
Cst _ | Eps | Mark _ | Pmark _ | Erase _ | Before _ | After _ ->
|
||||
mk_expr ids x.def
|
||||
| Alt l ->
|
||||
mk_expr ids (Alt (List.map (rename ids) l))
|
||||
| Seq (k, y, z) ->
|
||||
mk_expr ids (Seq (k, rename ids y, rename ids z))
|
||||
| Rep (g, k, y) ->
|
||||
mk_expr ids (Rep (g, k, rename ids y))
|
||||
|
||||
(****)
|
||||
|
||||
type hash = int
|
||||
type mark_infos = int array
|
||||
type status = Failed | Match of mark_infos * Pmark.Set.t | Running
|
||||
|
||||
module E = struct
|
||||
type t =
|
||||
| TSeq of t list * expr * sem
|
||||
| TExp of Marks.t * expr
|
||||
| TMatch of Marks.t
|
||||
|
||||
let rec equal l1 l2 =
|
||||
match l1, l2 with
|
||||
| [], [] ->
|
||||
true
|
||||
| TSeq (l1', e1, _) :: r1, TSeq (l2', e2, _) :: r2 ->
|
||||
e1.id = e2.id && equal l1' l2' && equal r1 r2
|
||||
| TExp (marks1, e1) :: r1, TExp (marks2, e2) :: r2 ->
|
||||
e1.id = e2.id && marks1 = marks2 && equal r1 r2
|
||||
| TMatch marks1 :: r1, TMatch marks2 :: r2 ->
|
||||
marks1 = marks2 && equal r1 r2
|
||||
| _ ->
|
||||
false
|
||||
|
||||
let rec hash l accu =
|
||||
match l with
|
||||
| [] ->
|
||||
accu
|
||||
| TSeq (l', e, _) :: r ->
|
||||
hash r (hash_combine 0x172a1bce (hash_combine e.id (hash l' accu)))
|
||||
| TExp (marks, e) :: r ->
|
||||
hash r
|
||||
(hash_combine 0x2b4c0d77 (hash_combine e.id (Marks.hash marks accu)))
|
||||
| TMatch marks :: r ->
|
||||
hash r (hash_combine 0x1c205ad5 (Marks.hash marks accu))
|
||||
|
||||
let texp marks x = TExp (marks, x)
|
||||
|
||||
let tseq kind x y rem =
|
||||
match x with
|
||||
[] -> rem
|
||||
| [TExp (marks, {def = Eps ; _})] -> TExp (marks, y) :: rem
|
||||
| _ -> TSeq (x, y, kind) :: rem
|
||||
|
||||
let rec print_state_rec ch e y =
|
||||
match e with
|
||||
| TMatch marks ->
|
||||
Format.fprintf ch "@[<2>(Match@ %a)@]" Marks.pp_marks marks
|
||||
| TSeq (l', x, _kind) ->
|
||||
Format.fprintf ch "@[<2>(Seq@ ";
|
||||
print_state_lst ch l' x;
|
||||
Format.fprintf ch "@ %a)@]" pp x
|
||||
| TExp (marks, {def = Eps; _}) ->
|
||||
Format.fprintf ch "@[<2>(Exp@ %d@ (%a)@ (eps))@]" y.id Marks.pp_marks marks
|
||||
| TExp (marks, x) ->
|
||||
Format.fprintf ch "@[<2>(Exp@ %d@ (%a)@ %a)@]" x.id Marks.pp_marks marks pp x
|
||||
|
||||
and print_state_lst ch l y =
|
||||
match l with
|
||||
[] ->
|
||||
Format.fprintf ch "()"
|
||||
| e :: rem ->
|
||||
print_state_rec ch e y;
|
||||
List.iter
|
||||
(fun e ->
|
||||
Format.fprintf ch "@ | ";
|
||||
print_state_rec ch e y)
|
||||
rem
|
||||
|
||||
let pp ch t = print_state_lst ch [t] { id = 0; def = Eps }
|
||||
end
|
||||
|
||||
module State = struct
|
||||
type t =
|
||||
{ idx: idx
|
||||
; category: Category.t
|
||||
; desc: E.t list
|
||||
; mutable status: status option
|
||||
; hash: hash }
|
||||
|
||||
let dummy =
|
||||
{ idx = -1
|
||||
; category = Category.dummy
|
||||
; desc = []
|
||||
; status = None
|
||||
; hash = -1 }
|
||||
|
||||
let hash idx cat desc =
|
||||
E.hash desc (hash_combine idx (hash_combine (Category.to_int cat) 0)) land 0x3FFFFFFF
|
||||
|
||||
let mk idx cat desc =
|
||||
{ idx
|
||||
; category = cat
|
||||
; desc
|
||||
; status = None
|
||||
; hash = hash idx cat desc}
|
||||
|
||||
let create cat e = mk 0 cat [E.TExp (Marks.empty, e)]
|
||||
|
||||
let equal x y =
|
||||
(x.hash : int) = y.hash && (x.idx : int) = y.idx &&
|
||||
Category.equal x.category y.category && E.equal x.desc y.desc
|
||||
|
||||
let compare x y =
|
||||
let c = compare (x.hash : int) y.hash in
|
||||
if c <> 0 then c else
|
||||
let c = Category.compare x.category y.category in
|
||||
if c <> 0 then c else
|
||||
compare x.desc y.desc
|
||||
|
||||
type t' = t
|
||||
module Table = Hashtbl.Make(
|
||||
struct
|
||||
type t = t'
|
||||
let equal = equal
|
||||
let hash t = t.hash
|
||||
end)
|
||||
end
|
||||
|
||||
(**** Find a free index ****)
|
||||
|
||||
type working_area = bool array ref
|
||||
|
||||
let create_working_area () = ref [| false |]
|
||||
|
||||
let index_count w = Array.length !w
|
||||
|
||||
let reset_table a = Array.fill a 0 (Array.length a) false
|
||||
|
||||
let rec mark_used_indices tbl =
|
||||
List.iter (function
|
||||
| E.TSeq (l, _, _) -> mark_used_indices tbl l
|
||||
| E.TExp (marks, _)
|
||||
| E.TMatch marks ->
|
||||
List.iter (fun (_, i) -> if i >= 0 then tbl.(i) <- true)
|
||||
marks.Marks.marks)
|
||||
|
||||
let rec find_free tbl idx len =
|
||||
if idx = len || not tbl.(idx) then idx else find_free tbl (idx + 1) len
|
||||
|
||||
let free_index tbl_ref l =
|
||||
let tbl = !tbl_ref in
|
||||
reset_table tbl;
|
||||
mark_used_indices tbl l;
|
||||
let len = Array.length tbl in
|
||||
let idx = find_free tbl 0 len in
|
||||
if idx = len then tbl_ref := Array.make (2 * len) false;
|
||||
idx
|
||||
|
||||
(**** Computation of the next state ****)
|
||||
|
||||
let remove_matches = List.filter (function E.TMatch _ -> false | _ -> true)
|
||||
|
||||
let rec split_at_match_rec l' = function
|
||||
| [] -> assert false
|
||||
| E.TMatch _ :: r -> (List.rev l', remove_matches r)
|
||||
| x :: r -> split_at_match_rec (x :: l') r
|
||||
|
||||
let split_at_match l = split_at_match_rec [] l
|
||||
|
||||
let rec remove_duplicates prev l y =
|
||||
match l with
|
||||
[] ->
|
||||
([], prev)
|
||||
| E.TMatch _ as x :: _ -> (* Truncate after first match *)
|
||||
([x], prev)
|
||||
| E.TSeq (l', x, kind) :: r ->
|
||||
let (l'', prev') = remove_duplicates prev l' x in
|
||||
let (r', prev'') = remove_duplicates prev' r y in
|
||||
(E.tseq kind l'' x r', prev'')
|
||||
| E.TExp (_marks, {def = Eps; _}) as e :: r ->
|
||||
if List.memq y.id prev then
|
||||
remove_duplicates prev r y
|
||||
else
|
||||
let (r', prev') = remove_duplicates (y.id :: prev) r y in
|
||||
(e :: r', prev')
|
||||
| E.TExp (_marks, x) as e :: r ->
|
||||
if List.memq x.id prev then
|
||||
remove_duplicates prev r y
|
||||
else
|
||||
let (r', prev') = remove_duplicates (x.id :: prev) r y in
|
||||
(e :: r', prev')
|
||||
|
||||
let rec set_idx idx = function
|
||||
| [] ->
|
||||
[]
|
||||
| E.TMatch marks :: r ->
|
||||
E.TMatch (Marks.marks_set_idx marks idx) :: set_idx idx r
|
||||
| E.TSeq (l', x, kind) :: r ->
|
||||
E.TSeq (set_idx idx l', x, kind) :: set_idx idx r
|
||||
| E.TExp (marks, x) :: r ->
|
||||
E.TExp ((Marks.marks_set_idx marks idx), x) :: set_idx idx r
|
||||
|
||||
let filter_marks b e marks =
|
||||
{marks with Marks.marks = List.filter (fun (i, _) -> i < b || i > e) marks.Marks.marks }
|
||||
|
||||
let rec delta_1 marks c ~next_cat ~prev_cat x rem =
|
||||
(*Format.eprintf "%d@." x.id;*)
|
||||
match x.def with
|
||||
Cst s ->
|
||||
if Cset.mem c s then E.texp marks eps_expr :: rem else rem
|
||||
| Alt l ->
|
||||
delta_2 marks c ~next_cat ~prev_cat l rem
|
||||
| Seq (kind, y, z) ->
|
||||
let y' = delta_1 marks c ~next_cat ~prev_cat y [] in
|
||||
delta_seq c ~next_cat ~prev_cat kind y' z rem
|
||||
| Rep (rep_kind, kind, y) ->
|
||||
let y' = delta_1 marks c ~next_cat ~prev_cat y [] in
|
||||
let (y'', marks') =
|
||||
match
|
||||
first
|
||||
(function E.TMatch marks -> Some marks | _ -> None) y'
|
||||
with
|
||||
None -> (y', marks)
|
||||
| Some marks' -> (remove_matches y', marks')
|
||||
in
|
||||
begin match rep_kind with
|
||||
`Greedy -> E.tseq kind y'' x (E.TMatch marks' :: rem)
|
||||
| `Non_greedy -> E.TMatch marks :: E.tseq kind y'' x rem
|
||||
end
|
||||
| Eps ->
|
||||
E.TMatch marks :: rem
|
||||
| Mark i ->
|
||||
let marks = { marks with Marks.marks = (i, -1) :: List.remove_assq i marks.Marks.marks } in
|
||||
E.TMatch marks :: rem
|
||||
| Pmark i ->
|
||||
let marks = { marks with Marks.pmarks = Pmark.Set.add i marks.Marks.pmarks } in
|
||||
E.TMatch marks :: rem
|
||||
| Erase (b, e) ->
|
||||
E.TMatch (filter_marks b e marks) :: rem
|
||||
| Before cat'' ->
|
||||
if Category.intersect next_cat cat'' then E.TMatch marks :: rem else rem
|
||||
| After cat'' ->
|
||||
if Category.intersect prev_cat cat'' then E.TMatch marks :: rem else rem
|
||||
|
||||
and delta_2 marks c ~next_cat ~prev_cat l rem =
|
||||
match l with
|
||||
[] -> rem
|
||||
| y :: r ->
|
||||
delta_1 marks c ~next_cat ~prev_cat y
|
||||
(delta_2 marks c ~next_cat ~prev_cat r rem)
|
||||
|
||||
and delta_seq c ~next_cat ~prev_cat kind y z rem =
|
||||
match
|
||||
first (function E.TMatch marks -> Some marks | _ -> None) y
|
||||
with
|
||||
None ->
|
||||
E.tseq kind y z rem
|
||||
| Some marks ->
|
||||
match kind with
|
||||
`Longest ->
|
||||
E.tseq kind (remove_matches y) z
|
||||
(delta_1 marks c ~next_cat ~prev_cat z rem)
|
||||
| `Shortest ->
|
||||
delta_1 marks c ~next_cat ~prev_cat z
|
||||
(E.tseq kind (remove_matches y) z rem)
|
||||
| `First ->
|
||||
let (y', y'') = split_at_match y in
|
||||
E.tseq kind y' z
|
||||
(delta_1 marks c ~next_cat ~prev_cat z (E.tseq kind y'' z rem))
|
||||
|
||||
let rec delta_3 c ~next_cat ~prev_cat x rem =
|
||||
match x with
|
||||
E.TSeq (y, z, kind) ->
|
||||
let y' = delta_4 c ~next_cat ~prev_cat y [] in
|
||||
delta_seq c ~next_cat ~prev_cat kind y' z rem
|
||||
| E.TExp (marks, e) ->
|
||||
delta_1 marks c ~next_cat ~prev_cat e rem
|
||||
| E.TMatch _ ->
|
||||
x :: rem
|
||||
|
||||
and delta_4 c ~next_cat ~prev_cat l rem =
|
||||
match l with
|
||||
[] -> rem
|
||||
| y :: r ->
|
||||
delta_3 c ~next_cat ~prev_cat y
|
||||
(delta_4 c ~next_cat ~prev_cat r rem)
|
||||
|
||||
let delta tbl_ref next_cat char st =
|
||||
let prev_cat = st.State.category in
|
||||
let (expr', _) =
|
||||
remove_duplicates []
|
||||
(delta_4 char ~next_cat ~prev_cat st.State.desc [])
|
||||
eps_expr in
|
||||
let idx = free_index tbl_ref expr' in
|
||||
let expr'' = set_idx idx expr' in
|
||||
State.mk idx next_cat expr''
|
||||
|
||||
(****)
|
||||
|
||||
let rec red_tr = function
|
||||
| [] | [_] as l ->
|
||||
l
|
||||
| ((s1, st1) as tr1) :: ((s2, st2) as tr2) :: rem ->
|
||||
if State.equal st1 st2 then
|
||||
red_tr ((Cset.union s1 s2, st1) :: rem)
|
||||
else
|
||||
tr1 :: red_tr (tr2 :: rem)
|
||||
|
||||
let simpl_tr l =
|
||||
List.sort
|
||||
(fun (s1, _) (s2, _) -> compare s1 s2)
|
||||
(red_tr (List.sort (fun (_, st1) (_, st2) -> State.compare st1 st2) l))
|
||||
|
||||
(****)
|
||||
|
||||
let prepend_deriv = List.fold_right (fun (s, x) l -> Cset.prepend s x l)
|
||||
|
||||
let rec restrict s = function
|
||||
| [] -> []
|
||||
| (s', x') :: rem ->
|
||||
let s'' = Cset.inter s s' in
|
||||
if Cset.is_empty s''
|
||||
then restrict s rem
|
||||
else (s'', x') :: restrict s rem
|
||||
|
||||
let rec remove_marks b e rem =
|
||||
if b > e then rem else remove_marks b (e - 1) ((e, -2) :: rem)
|
||||
|
||||
let rec prepend_marks_expr m = function
|
||||
| E.TSeq (l, e', s) -> E.TSeq (prepend_marks_expr_lst m l, e', s)
|
||||
| E.TExp (m', e') -> E.TExp (Marks.merge m m', e')
|
||||
| E.TMatch m' -> E.TMatch (Marks.merge m m')
|
||||
|
||||
and prepend_marks_expr_lst m l =
|
||||
List.map (prepend_marks_expr m) l
|
||||
|
||||
let prepend_marks m =
|
||||
List.map (fun (s, x) -> (s, prepend_marks_expr_lst m x))
|
||||
|
||||
let rec deriv_1 all_chars categories marks cat x rem =
|
||||
match x.def with
|
||||
| Cst s ->
|
||||
Cset.prepend s [E.texp marks eps_expr] rem
|
||||
| Alt l ->
|
||||
deriv_2 all_chars categories marks cat l rem
|
||||
| Seq (kind, y, z) ->
|
||||
let y' = deriv_1 all_chars categories marks cat y [(all_chars, [])] in
|
||||
deriv_seq all_chars categories cat kind y' z rem
|
||||
| Rep (rep_kind, kind, y) ->
|
||||
let y' = deriv_1 all_chars categories marks cat y [(all_chars, [])] in
|
||||
List.fold_right
|
||||
(fun (s, z) rem ->
|
||||
let (z', marks') =
|
||||
match
|
||||
first
|
||||
(function E.TMatch marks -> Some marks | _ -> None)
|
||||
z
|
||||
with
|
||||
None -> (z, marks)
|
||||
| Some marks' -> (remove_matches z, marks')
|
||||
in
|
||||
Cset.prepend s
|
||||
(match rep_kind with
|
||||
`Greedy -> E.tseq kind z' x [E.TMatch marks']
|
||||
| `Non_greedy -> E.TMatch marks :: E.tseq kind z' x [])
|
||||
rem)
|
||||
y' rem
|
||||
| Eps ->
|
||||
Cset.prepend all_chars [E.TMatch marks] rem
|
||||
| Mark i ->
|
||||
Cset.prepend all_chars [E.TMatch {marks with Marks.marks = ((i, -1) :: List.remove_assq i marks.Marks.marks)}] rem
|
||||
| Pmark _ ->
|
||||
Cset.prepend all_chars [E.TMatch marks] rem
|
||||
| Erase (b, e) ->
|
||||
Cset.prepend all_chars
|
||||
[E.TMatch {marks with Marks.marks = (remove_marks b e (filter_marks b e marks).Marks.marks)}] rem
|
||||
| Before cat' ->
|
||||
Cset.prepend (List.assq cat' categories) [E.TMatch marks] rem
|
||||
| After cat' ->
|
||||
if Category.intersect cat cat' then Cset.prepend all_chars [E.TMatch marks] rem else rem
|
||||
|
||||
and deriv_2 all_chars categories marks cat l rem =
|
||||
match l with
|
||||
[] -> rem
|
||||
| y :: r -> deriv_1 all_chars categories marks cat y
|
||||
(deriv_2 all_chars categories marks cat r rem)
|
||||
|
||||
and deriv_seq all_chars categories cat kind y z rem =
|
||||
if
|
||||
List.exists
|
||||
(fun (_s, xl) ->
|
||||
List.exists (function E.TMatch _ -> true | _ -> false) xl)
|
||||
y
|
||||
then
|
||||
let z' = deriv_1 all_chars categories Marks.empty cat z [(all_chars, [])] in
|
||||
List.fold_right
|
||||
(fun (s, y) rem ->
|
||||
match
|
||||
first (function E.TMatch marks -> Some marks | _ -> None)
|
||||
y
|
||||
with
|
||||
None ->
|
||||
Cset.prepend s (E.tseq kind y z []) rem
|
||||
| Some marks ->
|
||||
let z'' = prepend_marks marks z' in
|
||||
match kind with
|
||||
`Longest ->
|
||||
Cset.prepend s (E.tseq kind (remove_matches y) z []) (
|
||||
prepend_deriv (restrict s z'') rem)
|
||||
| `Shortest ->
|
||||
prepend_deriv (restrict s z'') (
|
||||
Cset.prepend s (E.tseq kind (remove_matches y) z []) rem)
|
||||
| `First ->
|
||||
let (y', y'') = split_at_match y in
|
||||
Cset.prepend s (E.tseq kind y' z []) (
|
||||
prepend_deriv (restrict s z'') (
|
||||
Cset.prepend s (E.tseq kind y'' z []) rem)))
|
||||
y rem
|
||||
else
|
||||
List.fold_right
|
||||
(fun (s, xl) rem -> Cset.prepend s (E.tseq kind xl z []) rem) y rem
|
||||
|
||||
let rec deriv_3 all_chars categories cat x rem =
|
||||
match x with
|
||||
E.TSeq (y, z, kind) ->
|
||||
let y' = deriv_4 all_chars categories cat y [(all_chars, [])] in
|
||||
deriv_seq all_chars categories cat kind y' z rem
|
||||
| E.TExp (marks, e) ->
|
||||
deriv_1 all_chars categories marks cat e rem
|
||||
| E.TMatch _ ->
|
||||
Cset.prepend all_chars [x] rem
|
||||
|
||||
and deriv_4 all_chars categories cat l rem =
|
||||
match l with
|
||||
[] -> rem
|
||||
| y :: r -> deriv_3 all_chars categories cat y
|
||||
(deriv_4 all_chars categories cat r rem)
|
||||
|
||||
let deriv tbl_ref all_chars categories st =
|
||||
let der = deriv_4 all_chars categories st.State.category st.State.desc
|
||||
[(all_chars, [])] in
|
||||
simpl_tr (
|
||||
List.fold_right (fun (s, expr) rem ->
|
||||
let (expr', _) = remove_duplicates [] expr eps_expr in
|
||||
(*
|
||||
Format.eprintf "@[<3>@[%a@]: %a / %a@]@." Cset.print s print_state expr print_state expr';
|
||||
*)
|
||||
let idx = free_index tbl_ref expr' in
|
||||
let expr'' = set_idx idx expr' in
|
||||
List.fold_right (fun (cat', s') rem ->
|
||||
let s'' = Cset.inter s s' in
|
||||
if Cset.is_empty s''
|
||||
then rem
|
||||
else (s'', State.mk idx cat' expr'') :: rem)
|
||||
categories rem) der [])
|
||||
|
||||
(****)
|
||||
|
||||
let flatten_match m =
|
||||
let ma = List.fold_left (fun ma (i, _) -> max ma i) (-1) m in
|
||||
let res = Array.make (ma + 1) (-1) in
|
||||
List.iter (fun (i, v) -> res.(i) <- v) m;
|
||||
res
|
||||
|
||||
let status s =
|
||||
match s.State.status with
|
||||
Some st ->
|
||||
st
|
||||
| None ->
|
||||
let st =
|
||||
match s.State.desc with
|
||||
[] -> Failed
|
||||
| E.TMatch m :: _ -> Match (flatten_match m.Marks.marks, m.Marks.pmarks)
|
||||
| _ -> Running
|
||||
in
|
||||
s.State.status <- Some st;
|
||||
st
|
||||
101
unikernel/duniverse/dune_/vendor/re/src/automata.mli
vendored
Normal file
101
unikernel/duniverse/dune_/vendor/re/src/automata.mli
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(* Regular expressions *)
|
||||
|
||||
type mark = int
|
||||
|
||||
type sem = [ `Longest | `Shortest | `First ]
|
||||
type rep_kind = [ `Greedy | `Non_greedy ]
|
||||
|
||||
val pp_sem : Format.formatter -> sem -> unit
|
||||
val pp_rep_kind : Format.formatter -> rep_kind -> unit
|
||||
|
||||
type expr
|
||||
val is_eps : expr -> bool
|
||||
val pp : Format.formatter -> expr -> unit
|
||||
|
||||
type ids
|
||||
val create_ids : unit -> ids
|
||||
|
||||
val cst : ids -> Cset.t -> expr
|
||||
val empty : ids -> expr
|
||||
val alt : ids -> expr list -> expr
|
||||
val seq : ids -> sem -> expr -> expr -> expr
|
||||
val eps : ids -> expr
|
||||
val rep : ids -> rep_kind -> sem -> expr -> expr
|
||||
val mark : ids -> mark -> expr
|
||||
val pmark : ids -> Pmark.t -> expr
|
||||
val erase : ids -> mark -> mark -> expr
|
||||
val before : ids -> Category.t -> expr
|
||||
val after : ids -> Category.t -> expr
|
||||
|
||||
val rename : ids -> expr -> expr
|
||||
|
||||
(****)
|
||||
|
||||
(* States of the automata *)
|
||||
|
||||
type idx = int
|
||||
module Marks : sig
|
||||
type t =
|
||||
{ marks: (mark * idx) list
|
||||
; pmarks: Pmark.Set.t }
|
||||
end
|
||||
|
||||
module E : sig
|
||||
type t
|
||||
val pp : Format.formatter -> t -> unit
|
||||
end
|
||||
|
||||
type hash
|
||||
type mark_infos = int array
|
||||
type status = Failed | Match of mark_infos * Pmark.Set.t | Running
|
||||
|
||||
module State : sig
|
||||
type t =
|
||||
{ idx: idx
|
||||
; category: Category.t
|
||||
; desc: E.t list
|
||||
; mutable status: status option
|
||||
; hash: hash }
|
||||
val dummy : t
|
||||
val create : Category.t -> expr -> t
|
||||
module Table : Hashtbl.S with type key = t
|
||||
end
|
||||
|
||||
(****)
|
||||
|
||||
(* Computation of the states following a given state *)
|
||||
|
||||
type working_area
|
||||
val create_working_area : unit -> working_area
|
||||
val index_count : working_area -> int
|
||||
|
||||
val delta : working_area -> Category.t -> Cset.c -> State.t -> State.t
|
||||
val deriv :
|
||||
working_area -> Cset.t -> (Category.t * Cset.t) list -> State.t ->
|
||||
(Cset.t * State.t) list
|
||||
|
||||
(****)
|
||||
|
||||
val status : State.t -> status
|
||||
27
unikernel/duniverse/dune_/vendor/re/src/category.ml
vendored
Normal file
27
unikernel/duniverse/dune_/vendor/re/src/category.ml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
type t = int
|
||||
let equal (x : int) (y : int) = x = y
|
||||
let compare (x : int) (y : int) = compare x y
|
||||
let to_int x = x
|
||||
let pp = Format.pp_print_int
|
||||
|
||||
let intersect x y = x land y <> 0
|
||||
let (++) x y = x lor y
|
||||
|
||||
let dummy = -1
|
||||
let inexistant = 1
|
||||
let letter = 2
|
||||
let not_letter = 4
|
||||
let newline = 8
|
||||
let lastnewline = 16
|
||||
let search_boundary = 32
|
||||
|
||||
let from_char = function
|
||||
(* Should match [cword] definition *)
|
||||
| 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '\170' | '\181' | '\186'
|
||||
| '\192'..'\214' | '\216'..'\246' | '\248'..'\255' ->
|
||||
letter
|
||||
| '\n' ->
|
||||
not_letter ++ newline
|
||||
| _ ->
|
||||
not_letter
|
||||
25
unikernel/duniverse/dune_/vendor/re/src/category.mli
vendored
Normal file
25
unikernel/duniverse/dune_/vendor/re/src/category.mli
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
(** Categories represent the various kinds of characters that can be tested
|
||||
by look-ahead and look-behind operations.
|
||||
|
||||
This is more restricted than Cset, but faster.
|
||||
*)
|
||||
|
||||
type t
|
||||
val (++) : t -> t -> t
|
||||
val from_char : char -> t
|
||||
|
||||
val dummy : t
|
||||
val inexistant : t
|
||||
val letter : t
|
||||
val not_letter : t
|
||||
val newline : t
|
||||
val lastnewline : t
|
||||
val search_boundary : t
|
||||
val to_int : t -> int
|
||||
val equal : t -> t -> bool
|
||||
val compare : t -> t -> int
|
||||
|
||||
val intersect : t -> t -> bool
|
||||
|
||||
|
||||
val pp : Format.formatter -> t -> unit
|
||||
34
unikernel/duniverse/dune_/vendor/re/src/color_map.ml
vendored
Normal file
34
unikernel/duniverse/dune_/vendor/re/src/color_map.ml
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
(* In reality, this can really be represented as a bool array.
|
||||
|
||||
The representation is best thought of as a list of all chars along with a
|
||||
flag:
|
||||
|
||||
(a, 0), (b, 1), (c, 0), (d, 0), ...
|
||||
|
||||
characters belonging to the same color are represented by sequnces of
|
||||
characters with the flag set to 0.
|
||||
*)
|
||||
|
||||
type t = Bytes.t
|
||||
|
||||
let make () = Bytes.make 257 '\000'
|
||||
|
||||
let flatten cm =
|
||||
let c = Bytes.create 256 in
|
||||
let color_repr = Bytes.create 256 in
|
||||
let v = ref 0 in
|
||||
Bytes.set c 0 '\000';
|
||||
Bytes.set color_repr 0 '\000';
|
||||
for i = 1 to 255 do
|
||||
if Bytes.get cm i <> '\000' then incr v;
|
||||
Bytes.set c i (Char.chr !v);
|
||||
Bytes.set color_repr !v (Char.chr i)
|
||||
done;
|
||||
(Bytes.unsafe_to_string c, Bytes.sub_string color_repr 0 (!v + 1), !v + 1)
|
||||
|
||||
(* mark all the endpoints of the intervals of the char set with the 1 byte *)
|
||||
let split s cm =
|
||||
Cset.iter s ~f:(fun i j ->
|
||||
Bytes.set cm i '\001';
|
||||
Bytes.set cm (j + 1) '\001';
|
||||
)
|
||||
14
unikernel/duniverse/dune_/vendor/re/src/color_map.mli
vendored
Normal file
14
unikernel/duniverse/dune_/vendor/re/src/color_map.mli
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
(* Color maps exists to provide an optimization for the regex engine. The fact
|
||||
that some characters are entirely equivalent for some regexes means that we
|
||||
can use them interchangeably.
|
||||
|
||||
A color map assigns a color to every character in our character set. Any two
|
||||
characters with the same color will be treated equivalently by the automaton.
|
||||
*)
|
||||
type t
|
||||
|
||||
val make : unit -> t
|
||||
|
||||
val flatten : t -> string * string * int
|
||||
|
||||
val split : Cset.t -> t -> unit
|
||||
1266
unikernel/duniverse/dune_/vendor/re/src/core.ml
vendored
Normal file
1266
unikernel/duniverse/dune_/vendor/re/src/core.ml
vendored
Normal file
File diff suppressed because it is too large
Load diff
749
unikernel/duniverse/dune_/vendor/re/src/core.mli
vendored
Normal file
749
unikernel/duniverse/dune_/vendor/re/src/core.mli
vendored
Normal file
|
|
@ -0,0 +1,749 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(** Module [Re]: code for creating and using regular expressions,
|
||||
independently of regular expression syntax. *)
|
||||
|
||||
type t
|
||||
(** Regular expression *)
|
||||
|
||||
type re
|
||||
(** Compiled regular expression *)
|
||||
|
||||
(** Manipulate matching groups. *)
|
||||
module Group : sig
|
||||
type t
|
||||
(** Information about groups in a match. As is conventional, every
|
||||
match implicitly has a group 0 that covers the whole match, and
|
||||
explicit groups are numbered from 1. *)
|
||||
|
||||
val get : t -> int -> string
|
||||
(** Raise [Not_found] if the group did not match *)
|
||||
|
||||
val get_opt : t -> int -> string option
|
||||
(** Similar to {!get}, but returns an option instead of using an exception. *)
|
||||
|
||||
val offset : t -> int -> int * int
|
||||
(** Raise [Not_found] if the group did not match *)
|
||||
|
||||
val start : t -> int -> int
|
||||
(** Return the start of the match. Raise [Not_found] if the group did not match. *)
|
||||
|
||||
val stop : t -> int -> int
|
||||
(** Return the end of the match. Raise [Not_found] if the group did not match. *)
|
||||
|
||||
val all : t -> string array
|
||||
(** Return the empty string for each group which did not match *)
|
||||
|
||||
val all_offset : t -> (int * int) array
|
||||
(** Return [(-1,-1)] for each group which did not match *)
|
||||
|
||||
val test : t -> int -> bool
|
||||
(** Test whether a group matched *)
|
||||
|
||||
val nb_groups : t -> int
|
||||
(** Returns the total number of groups defined - matched or not.
|
||||
This function is experimental. *)
|
||||
|
||||
val pp : Format.formatter -> t -> unit
|
||||
end
|
||||
type groups = Group.t [@@ocaml.deprecated "Use Group.t"]
|
||||
|
||||
(** {2 Compilation and execution of a regular expression} *)
|
||||
|
||||
val compile : t -> re
|
||||
(** Compile a regular expression into an executable version that can be
|
||||
used to match strings, e.g. with {!exec}. *)
|
||||
|
||||
val group_count : re -> int
|
||||
(** Return the number of capture groups (including the one
|
||||
corresponding to the entire regexp). *)
|
||||
|
||||
val group_names : re -> (string * int) list
|
||||
(** Return named capture groups with their index. *)
|
||||
|
||||
val exec :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int -> (** Default: -1 (until end of string) *)
|
||||
re -> string -> Group.t
|
||||
(** [exec re str] searches [str] for a match of the compiled expression [re],
|
||||
and returns the matched groups if any.
|
||||
|
||||
More specifically, when a match exists, [exec] returns a match that
|
||||
starts at the earliest position possible. If multiple such matches are
|
||||
possible, the one specified by the match semantics described below is
|
||||
returned.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "//"; rep print ]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.exec regex "// a C comment";;
|
||||
- : Re.substrings = <abstr>
|
||||
|
||||
# Re.exec regex "# a C comment?";;
|
||||
Exception: Not_found
|
||||
|
||||
# Re.exec ~pos:1 regex "// a C comment";;
|
||||
Exception: Not_found
|
||||
]}
|
||||
|
||||
|
||||
@param pos optional beginning of the string (default 0)
|
||||
@param len length of the substring of [str] that can be matched (default [-1],
|
||||
meaning to the end of the string)
|
||||
@raise Not_found if the regular expression can't be found in [str]
|
||||
*)
|
||||
|
||||
val exec_opt :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int -> (** Default: -1 (until end of string) *)
|
||||
re -> string -> Group.t option
|
||||
(** Similar to {!exec}, but returns an option instead of using an exception.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "//"; rep print ]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.exec_opt regex "// a C comment";;
|
||||
- : Re.substrings option = Some <abstr>
|
||||
|
||||
# Re.exec_opt regex "# a C comment?";;
|
||||
- : Re.substrings option = None
|
||||
|
||||
# Re.exec_opt ~pos:1 regex "// a C comment";;
|
||||
- : Re.substrings option = None
|
||||
]}
|
||||
*)
|
||||
|
||||
val execp :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int -> (** Default: -1 (until end of string) *)
|
||||
re -> string -> bool
|
||||
(** Similar to {!exec}, but returns [true] if the expression matches,
|
||||
and [false] if it doesn't. This function is more efficient than
|
||||
calling {!exec} or {!exec_opt} and ignoring the returned group.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "//"; rep print ]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.execp regex "// a C comment";;
|
||||
- : bool = true
|
||||
|
||||
# Re.execp ~pos:1 regex "// a C comment";;
|
||||
- : bool = false
|
||||
]}
|
||||
*)
|
||||
|
||||
val exec_partial :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int -> (** Default: -1 (until end of string) *)
|
||||
re -> string -> [ `Full | `Partial | `Mismatch ]
|
||||
(** More detailed version of {!execp}. [`Full] is equivalent to [true],
|
||||
while [`Mismatch] and [`Partial] are equivalent to [false], but [`Partial]
|
||||
indicates the input string could be extended to create a match.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [bos; str "// a C comment"]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.exec_partial regex "// a C comment here.";;
|
||||
- : [ `Full | `Mismatch | `Partial ] = `Full
|
||||
|
||||
# Re.exec_partial regex "// a C comment";;
|
||||
- : [ `Full | `Mismatch | `Partial ] = `Partial
|
||||
|
||||
# Re.exec_partial regex "//";;
|
||||
- : [ `Full | `Mismatch | `Partial ] = `Partial
|
||||
|
||||
# Re.exec_partial regex "# a C comment?";;
|
||||
- : [ `Full | `Mismatch | `Partial ] = `Mismatch
|
||||
]}
|
||||
*)
|
||||
|
||||
val exec_partial_detailed :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int -> (** Default: -1 (until end of string) *)
|
||||
re -> string -> [ `Full of Group.t | `Partial of int | `Mismatch ]
|
||||
(** More detailed version of {!exec_opt}. [`Full group] is equivalent to [Some group],
|
||||
while [`Mismatch] and [`Partial _] are equivalent to [None], but [`Partial position]
|
||||
indicates that the input string could be extended to create a match, and no match could
|
||||
start in the input string before the given position.
|
||||
This could be used to not have to search the entirety of the input if more
|
||||
becomes available, and use the given position as the [?pos] argument.
|
||||
*)
|
||||
|
||||
(** Marks *)
|
||||
module Mark : sig
|
||||
|
||||
type t
|
||||
(** Mark id *)
|
||||
|
||||
val test : Group.t -> t -> bool
|
||||
(** Tell if a mark was matched. *)
|
||||
|
||||
module Set : Set.S with type elt = t
|
||||
|
||||
val all : Group.t -> Set.t
|
||||
(** Return all the mark matched. *)
|
||||
|
||||
val equal : t -> t -> bool
|
||||
val compare : t -> t -> int
|
||||
|
||||
end
|
||||
|
||||
(** {2 High Level Operations} *)
|
||||
|
||||
type split_token =
|
||||
[ `Text of string (** Text between delimiters *)
|
||||
| `Delim of Group.t (** Delimiter *)
|
||||
]
|
||||
|
||||
val all : ?pos:int -> ?len:int -> re -> string -> Group.t list
|
||||
(** Repeatedly calls {!exec} on the given string, starting at given position and
|
||||
length.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "my"; blank; word(rep alpha)]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.all regex "my head, my shoulders, my knees, my toes ...";;
|
||||
- : Re.substrings list = [<abstr>; <abstr>; <abstr>; <abstr>]
|
||||
|
||||
# Re.all regex "My head, My shoulders, My knees, My toes ...";;
|
||||
- : Re.substrings list = []
|
||||
]}
|
||||
*)
|
||||
|
||||
type 'a gen = unit -> 'a option
|
||||
|
||||
val all_gen : ?pos:int -> ?len:int -> re -> string -> Group.t gen
|
||||
[@@ocaml.deprecated "Use Seq.all"]
|
||||
(** @deprecated Use {!module-Seq.all} instead. *)
|
||||
|
||||
val all_seq : ?pos:int -> ?len:int -> re -> string -> Group.t Seq.t
|
||||
[@@ocaml.deprecated "Use Seq.all"]
|
||||
(** @deprecated Use {!module-Seq.all} instead. *)
|
||||
|
||||
val matches : ?pos:int -> ?len:int -> re -> string -> string list
|
||||
(** Same as {!all}, but extracts the matched substring rather than returning
|
||||
the whole group. This basically iterates over matched strings.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "my"; blank; word(rep alpha)]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.matches regex "my head, my shoulders, my knees, my toes ...";;
|
||||
- : string list = ["my head"; "my shoulders"; "my knees"; "my toes"]
|
||||
|
||||
# Re.matches regex "My head, My shoulders, My knees, My toes ...";;
|
||||
- : string list = []
|
||||
|
||||
# Re.matches regex "my my my my head my 1 toe my ...";;
|
||||
- : string list = ["my my"; "my my"]
|
||||
|
||||
# Re.matches ~pos:2 regex "my my my my head my +1 toe my ...";;
|
||||
- : string list = ["my my"; "my head"]
|
||||
]}
|
||||
*)
|
||||
|
||||
val matches_gen : ?pos:int -> ?len:int -> re -> string -> string gen
|
||||
[@@ocaml.deprecated "Use Seq.matches"]
|
||||
(** @deprecated Use {!module-Seq.matches} instead. *)
|
||||
|
||||
val matches_seq : ?pos:int -> ?len:int -> re -> string -> string Seq.t
|
||||
[@@ocaml.deprecated "Use Seq.matches"]
|
||||
(** @deprecated Use {!module-Seq.matches} instead. *)
|
||||
|
||||
val split : ?pos:int -> ?len:int -> re -> string -> string list
|
||||
(** [split re s] splits [s] into chunks separated by [re]. It yields the chunks
|
||||
themselves, not the separator.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile (Re.char ',');;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.split regex "Re,Ocaml,Jerome Vouillon";;
|
||||
- : string list = ["Re"; "Ocaml"; "Jerome Vouillon"]
|
||||
|
||||
# Re.split regex "No commas in this sentence.";;
|
||||
- : string list = ["No commas in this sentence."]
|
||||
|
||||
# Re.split ~pos:3 regex "1,2,3,4. Commas go brrr.";;
|
||||
- : string list = ["3"; "4. Commas go brrr."]
|
||||
]}
|
||||
*)
|
||||
|
||||
val split_gen : ?pos:int -> ?len:int -> re -> string -> string gen
|
||||
[@@ocaml.deprecated "Use Seq.split"]
|
||||
(** @deprecated Use {!module-Seq.split} instead. *)
|
||||
|
||||
val split_seq : ?pos:int -> ?len:int -> re -> string -> string Seq.t
|
||||
[@@ocaml.deprecated "Use Seq.split"]
|
||||
(** @deprecated Use {!module-Seq.split} instead. *)
|
||||
|
||||
val split_full : ?pos:int -> ?len:int -> re -> string -> split_token list
|
||||
(** [split re s] splits [s] into chunks separated by [re]. It yields the chunks
|
||||
along with the separators. For instance this can be used with a
|
||||
whitespace-matching re such as ["[\t ]+"].
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile (Re.char ',');;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.split_full regex "Re,Ocaml,Jerome Vouillon";;
|
||||
- : Re.split_token list =
|
||||
[`Text "Re"; `Delim <abstr>; `Text "Ocaml"; `Delim <abstr>;
|
||||
`Text "Jerome Vouillon"]
|
||||
|
||||
# Re.split_full regex "No commas in this sentence.";;
|
||||
- : Re.split_token list = [`Text "No commas in this sentence."]
|
||||
|
||||
# Re.split_full ~pos:3 regex "1,2,3,4. Commas go brrr.";;
|
||||
- : Re.split_token list =
|
||||
[`Delim <abstr>; `Text "3"; `Delim <abstr>; `Text "4. Commas go brrr."]
|
||||
]}
|
||||
*)
|
||||
|
||||
val split_full_gen : ?pos:int -> ?len:int -> re -> string -> split_token gen
|
||||
[@@ocaml.deprecated "Use Seq.split_full"]
|
||||
(** @deprecated Use {!module-Seq.split_full} instead. *)
|
||||
|
||||
val split_full_seq : ?pos:int -> ?len:int -> re -> string -> split_token Seq.t
|
||||
[@@ocaml.deprecated "Use Seq.split_full"]
|
||||
(** @deprecated Use {!module-Seq.split_full} instead. *)
|
||||
|
||||
module Seq : sig
|
||||
val all :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int ->
|
||||
re -> string -> Group.t Seq.t
|
||||
(** Same as {!module-Re.val-all} but returns an iterator.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "my"; blank; word(rep alpha)]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.Seq.all regex "my head, my shoulders, my knees, my toes ...";;
|
||||
- : Re.substrings Seq.t = <fun>
|
||||
]}
|
||||
@since 1.10.0 *)
|
||||
|
||||
val matches :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int ->
|
||||
re -> string -> string Seq.t
|
||||
(** Same as {!module-Re.val-matches}, but returns an iterator.
|
||||
|
||||
{5 Example:}
|
||||
{[
|
||||
# let regex = Re.compile Re.(seq [str "my"; blank; word(rep alpha)]);;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.Seq.matches regex "my head, my shoulders, my knees, my toes ...";;
|
||||
- : string Seq.t = <fun>
|
||||
]}
|
||||
@since 1.10.0 *)
|
||||
|
||||
val split :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int ->
|
||||
re -> string -> string Seq.t
|
||||
(** Same as {!module-Re.val-split} but returns an iterator.
|
||||
|
||||
{5 Example:}
|
||||
{[
|
||||
# let regex = Re.compile (Re.char ',');;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.Seq.split regex "Re,Ocaml,Jerome Vouillon";;
|
||||
- : string Seq.t = <fun>
|
||||
]}
|
||||
@since 1.10.0 *)
|
||||
|
||||
val split_full :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int ->
|
||||
re -> string -> split_token Seq.t
|
||||
(** Same as {!module-Re.val-split_full} but returns an iterator.
|
||||
|
||||
{5 Example:}
|
||||
{[
|
||||
# let regex = Re.compile (Re.char ',');;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.Seq.split_full regex "Re,Ocaml,Jerome Vouillon";;
|
||||
- : Re__Core.split_token Seq.t = <fun>
|
||||
]}
|
||||
@since 1.10.0 *)
|
||||
end
|
||||
|
||||
val replace :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int ->
|
||||
?all:bool -> (** Default: true. Otherwise only replace first occurrence *)
|
||||
re -> (** matched groups *)
|
||||
f:(Group.t -> string) -> (** how to replace *)
|
||||
string -> (** string to replace in *)
|
||||
string
|
||||
(** [replace ~all re ~f s] iterates on [s], and replaces every occurrence
|
||||
of [re] with [f substring] where [substring] is the current match.
|
||||
If [all = false], then only the first occurrence of [re] is replaced. *)
|
||||
|
||||
val replace_string :
|
||||
?pos:int -> (** Default: 0 *)
|
||||
?len:int ->
|
||||
?all:bool -> (** Default: true. Otherwise only replace first occurrence *)
|
||||
re -> (** matched groups *)
|
||||
by:string -> (** replacement string *)
|
||||
string -> (** string to replace in *)
|
||||
string
|
||||
(** [replace_string ~all re ~by s] iterates on [s], and replaces every
|
||||
occurrence of [re] with [by]. If [all = false], then only the first
|
||||
occurrence of [re] is replaced.
|
||||
|
||||
{5 Examples:}
|
||||
{[
|
||||
# let regex = Re.compile (Re.char ',');;
|
||||
val regex : re = <abstr>
|
||||
|
||||
# Re.replace_string regex ~by:";" "[1,2,3,4,5,6,7]";;
|
||||
- : string = "[1;2;3;4;5;6;7]"
|
||||
|
||||
# Re.replace_string regex ~all:false ~by:";" "[1,2,3,4,5,6,7]";;
|
||||
- : string = "[1;2,3,4,5,6,7]"
|
||||
]}
|
||||
*)
|
||||
|
||||
(** {2 String expressions (literal match)} *)
|
||||
|
||||
val str : string -> t
|
||||
val char : char -> t
|
||||
|
||||
(** {2 Basic operations on regular expressions} *)
|
||||
|
||||
val alt : t list -> t
|
||||
(** Alternative.
|
||||
|
||||
[alt []] is equivalent to {!empty}.
|
||||
|
||||
By default, the leftmost match is preferred (see match semantics below).
|
||||
*)
|
||||
|
||||
val seq : t list -> t
|
||||
(** Sequence *)
|
||||
|
||||
val empty : t
|
||||
(** Match nothing *)
|
||||
|
||||
val epsilon : t
|
||||
(** Empty word *)
|
||||
|
||||
val rep : t -> t
|
||||
(** 0 or more matches *)
|
||||
|
||||
val rep1 : t -> t
|
||||
(** 1 or more matches *)
|
||||
|
||||
val repn : t -> int -> int option -> t
|
||||
(** [repn re i j] matches [re] at least [i] times
|
||||
and at most [j] times, bounds included.
|
||||
[j = None] means no upper bound.
|
||||
*)
|
||||
|
||||
val opt : t -> t
|
||||
(** 0 or 1 matches *)
|
||||
|
||||
(** {2 String, line, word}
|
||||
|
||||
We define a word as a sequence of latin1 letters, digits and underscore.
|
||||
*)
|
||||
|
||||
val bol : t
|
||||
(** Beginning of line *)
|
||||
|
||||
val eol : t
|
||||
(** End of line *)
|
||||
|
||||
val bow : t
|
||||
(** Beginning of word *)
|
||||
|
||||
val eow : t
|
||||
(** End of word *)
|
||||
|
||||
val bos : t
|
||||
(** Beginning of string. This differs from {!start} because it matches
|
||||
the beginning of the input string even when using [~pos] arguments:
|
||||
|
||||
{[
|
||||
let b = execp (compile (seq [ bos; str "a" ])) "aa" ~pos:1 in
|
||||
assert (not b)
|
||||
]}
|
||||
*)
|
||||
|
||||
val eos : t
|
||||
(** End of string. This is different from {!stop} in the way described
|
||||
in {!bos}. *)
|
||||
|
||||
val leol : t
|
||||
(** Last end of line or end of string *)
|
||||
|
||||
val start : t
|
||||
(** Initial position. This differs from {!bos} because it takes into
|
||||
account the [~pos] arguments:
|
||||
|
||||
{[
|
||||
let b = execp (compile (seq [ start; str "a" ])) "aa" ~pos:1 in
|
||||
assert b
|
||||
]}
|
||||
*)
|
||||
|
||||
val stop : t
|
||||
(** Final position. This is different from {!eos} in the way described
|
||||
in {!start}. *)
|
||||
|
||||
val word : t -> t
|
||||
(** Word *)
|
||||
|
||||
val not_boundary : t
|
||||
(** Not at a word boundary *)
|
||||
|
||||
val whole_string : t -> t
|
||||
(** Only matches the whole string, i.e. [fun t -> seq [ eos; t; bos ]]. *)
|
||||
|
||||
(** {2 Match semantics}
|
||||
|
||||
A regular expression frequently matches a string in multiple ways. For
|
||||
instance [exec (compile (opt (str "a"))) "ab"] can match "" or "a". Match
|
||||
semantic can be modified with the functions below, allowing one to choose
|
||||
which of these is preferable.
|
||||
|
||||
By default, the leftmost branch of alternations is preferred, and repetitions
|
||||
are greedy.
|
||||
|
||||
Note that the existence of matches cannot be changed by specifying match
|
||||
semantics. [seq [ bos; str "a"; non_greedy (opt (str "b")); eos ]] will
|
||||
match when applied to "ab". However if [seq [ bos; str "a"; non_greedy (opt
|
||||
(str "b")) ]] is applied to "ab", it will match "a" rather than "ab".
|
||||
|
||||
Also note that multiple match semantics can conflict. In this case, the one
|
||||
executed earlier takes precedence. For instance, any match of [shortest (seq
|
||||
[ bos; group (rep (str "a")); group (rep (str "a")); eos ])] will always have
|
||||
an empty first group. Conversely, if we use [longest] instead of [shortest],
|
||||
the second group will always be empty.
|
||||
*)
|
||||
|
||||
val longest : t -> t
|
||||
(** Longest match semantics. That is, matches will match as many bytes as
|
||||
possible. If multiple choices match the maximum amount of bytes, the one
|
||||
respecting the inner match semantics is preferred. *)
|
||||
|
||||
val shortest : t -> t
|
||||
(** Same as {!longest}, but matching the least number of bytes. *)
|
||||
|
||||
val first : t -> t
|
||||
(** First match semantics for alternations (not repetitions). That is, matches
|
||||
will prefer the leftmost branch of the alternation that matches the text. *)
|
||||
|
||||
val greedy : t -> t
|
||||
(** Greedy matches for repetitions ({!opt}, {!rep}, {!rep1}, {!repn}): they will
|
||||
match as many times as possible. *)
|
||||
|
||||
val non_greedy : t -> t
|
||||
(** Non-greedy matches for repetitions ({!opt}, {!rep}, {!rep1}, {!repn}): they
|
||||
will match as few times as possible. *)
|
||||
|
||||
(** {2 Groups (or submatches)} *)
|
||||
|
||||
val group : ?name:string -> t -> t
|
||||
(** Delimit a group. The group is considered as matching if it is used at least
|
||||
once (it may be used multiple times if is nested inside {!rep} for
|
||||
instance). If it is used multiple times, the last match is what gets
|
||||
captured. *)
|
||||
|
||||
val no_group : t -> t
|
||||
(** Remove all groups *)
|
||||
|
||||
val nest : t -> t
|
||||
(** When matching against [nest e], only the group matching in the
|
||||
last match of e will be considered as matching.
|
||||
|
||||
For instance:
|
||||
{[
|
||||
let re = compile (rep1 (nest (alt [ group (str "a"); str "b" ]))) in
|
||||
let group = Re.exec re "ab" in
|
||||
assert (Group.get_opt group 1 = None);
|
||||
|
||||
(* same thing but without [nest] *)
|
||||
let re = compile (rep1 (alt [ group (str "a"); str "b" ])) in
|
||||
let group = Re.exec re "ab" in
|
||||
assert (Group.get_opt group 1 = Some "a");
|
||||
]}
|
||||
*)
|
||||
|
||||
|
||||
|
||||
val mark : t -> Mark.t * t
|
||||
(** Mark a regexp. the markid can then be used to know if this regexp was used. *)
|
||||
|
||||
(** {2 Character sets} *)
|
||||
|
||||
val set : string -> t
|
||||
(** Any character of the string *)
|
||||
|
||||
val rg : char -> char -> t
|
||||
(** Character ranges *)
|
||||
|
||||
val inter : t list -> t
|
||||
(** Intersection of character sets *)
|
||||
|
||||
val diff : t -> t -> t
|
||||
(** Difference of character sets *)
|
||||
|
||||
val compl : t list -> t
|
||||
(** Complement of union *)
|
||||
|
||||
(** {2 Predefined character sets} *)
|
||||
|
||||
val any : t
|
||||
(** Any character *)
|
||||
|
||||
val notnl : t
|
||||
(** Any character but a newline *)
|
||||
|
||||
val alnum : t
|
||||
val wordc : t
|
||||
val alpha : t
|
||||
val ascii : t
|
||||
val blank : t
|
||||
val cntrl : t
|
||||
val digit : t
|
||||
val graph : t
|
||||
val lower : t
|
||||
val print : t
|
||||
val punct : t
|
||||
val space : t
|
||||
val upper : t
|
||||
val xdigit : t
|
||||
|
||||
(** {2 Case modifiers} *)
|
||||
|
||||
val case : t -> t
|
||||
(** Case sensitive matching. Note that this works on latin1, not ascii and not
|
||||
utf8. *)
|
||||
|
||||
val no_case : t -> t
|
||||
(** Case insensitive matching. Note that this works on latin1, not ascii and not
|
||||
utf8. *)
|
||||
|
||||
(****)
|
||||
|
||||
(** {2 Internal debugging} *)
|
||||
|
||||
val pp : Format.formatter -> t -> unit
|
||||
|
||||
val pp_re : Format.formatter -> re -> unit
|
||||
|
||||
(** Alias for {!pp_re}. Deprecated *)
|
||||
val print_re : Format.formatter -> re -> unit
|
||||
|
||||
module View : sig
|
||||
type outer
|
||||
|
||||
(** A view of the top-level of a regex. This type is unstable and may change *)
|
||||
type t =
|
||||
Set of Cset.t
|
||||
| Sequence of outer list
|
||||
| Alternative of outer list
|
||||
| Repeat of outer * int * int option
|
||||
| Beg_of_line | End_of_line
|
||||
| Beg_of_word | End_of_word | Not_bound
|
||||
| Beg_of_str | End_of_str
|
||||
| Last_end_of_line | Start | Stop
|
||||
| Sem of Automata.sem * outer
|
||||
| Sem_greedy of Automata.rep_kind * outer
|
||||
| Group of string option * outer | No_group of outer | Nest of outer
|
||||
| Case of outer | No_case of outer
|
||||
| Intersection of outer list
|
||||
| Complement of outer list
|
||||
| Difference of outer * outer
|
||||
| Pmark of Pmark.t * outer
|
||||
|
||||
val view : outer -> t
|
||||
end with type outer := t
|
||||
|
||||
(** {2 Experimental functions} *)
|
||||
|
||||
val witness : t -> string
|
||||
(** [witness r] generates a string [s] such that [execp (compile r) s] is true.
|
||||
|
||||
Be warned that this function is buggy because it ignores zero-width
|
||||
assertions like beginning of words. As a result it can generate incorrect
|
||||
results. *)
|
||||
|
||||
(** {2 Deprecated functions} *)
|
||||
|
||||
type substrings = Group.t
|
||||
[@@ocaml.deprecated "Use Group.t"]
|
||||
(** Alias for {!Group.t}. Deprecated *)
|
||||
|
||||
val get : Group.t -> int -> string
|
||||
[@@ocaml.deprecated "Use Group.get"]
|
||||
(** Same as {!Group.get}. Deprecated *)
|
||||
|
||||
val get_ofs : Group.t -> int -> int * int
|
||||
[@@ocaml.deprecated "Use Group.offset"]
|
||||
(** Same as {!Group.offset}. Deprecated *)
|
||||
|
||||
val get_all : Group.t -> string array
|
||||
[@@ocaml.deprecated "Use Group.all"]
|
||||
(** Same as {!Group.all}. Deprecated *)
|
||||
|
||||
val get_all_ofs : Group.t -> (int * int) array
|
||||
[@@ocaml.deprecated "Use Group.all_offset"]
|
||||
(** Same as {!Group.all_offset}. Deprecated *)
|
||||
|
||||
val test : Group.t -> int -> bool
|
||||
[@@ocaml.deprecated "Use Group.test"]
|
||||
(** Same as {!Group.test}. Deprecated *)
|
||||
|
||||
type markid = Mark.t
|
||||
[@@ocaml.deprecated "Use Mark."]
|
||||
(** Alias for {!Mark.t}. Deprecated *)
|
||||
|
||||
val marked : Group.t -> Mark.t -> bool
|
||||
[@@ocaml.deprecated "Use Mark.test"]
|
||||
(** Same as {!Mark.test}. Deprecated *)
|
||||
|
||||
val mark_set : Group.t -> Mark.Set.t
|
||||
[@@ocaml.deprecated "Use Mark.all"]
|
||||
(** Same as {!Mark.all}. Deprecated *)
|
||||
157
unikernel/duniverse/dune_/vendor/re/src/cset.ml
vendored
Normal file
157
unikernel/duniverse/dune_/vendor/re/src/cset.ml
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
type c = int
|
||||
type t = (c * c) list
|
||||
|
||||
let rec union l l' =
|
||||
match l, l' with
|
||||
_, [] -> l
|
||||
| [], _ -> l'
|
||||
| (c1, c2)::r, (c1', c2')::r' ->
|
||||
if c2 + 1 < c1' then
|
||||
(c1, c2)::union r l'
|
||||
else if c2' + 1 < c1 then
|
||||
(c1', c2')::union l r'
|
||||
else if c2 < c2' then
|
||||
union r ((min c1 c1', c2')::r')
|
||||
else
|
||||
union ((min c1 c1', c2)::r) r'
|
||||
|
||||
let rec inter l l' =
|
||||
match l, l' with
|
||||
_, [] -> []
|
||||
| [], _ -> []
|
||||
| (c1, c2)::r, (c1', c2')::r' ->
|
||||
if c2 < c1' then
|
||||
inter r l'
|
||||
else if c2' < c1 then
|
||||
inter l r'
|
||||
else if c2 < c2' then
|
||||
(max c1 c1', c2)::inter r l'
|
||||
else
|
||||
(max c1 c1', c2')::inter l r'
|
||||
|
||||
let rec diff l l' =
|
||||
match l, l' with
|
||||
_, [] -> l
|
||||
| [], _ -> []
|
||||
| (c1, c2)::r, (c1', c2')::r' ->
|
||||
if c2 < c1' then
|
||||
(c1, c2)::diff r l'
|
||||
else if c2' < c1 then
|
||||
diff l r'
|
||||
else
|
||||
let r'' = if c2' < c2 then (c2' + 1, c2) :: r else r in
|
||||
if c1 < c1' then
|
||||
(c1, c1' - 1)::diff r'' r'
|
||||
else
|
||||
diff r'' r'
|
||||
|
||||
let single c = [c, c]
|
||||
|
||||
let add c l = union (single c) l
|
||||
|
||||
let seq c c' = if c <= c' then [c, c'] else [c', c]
|
||||
|
||||
let rec offset o l =
|
||||
match l with
|
||||
[] -> []
|
||||
| (c1, c2) :: r -> (c1 + o, c2 + o) :: offset o r
|
||||
|
||||
let empty = []
|
||||
|
||||
let rec mem (c : int) s =
|
||||
match s with
|
||||
[] -> false
|
||||
| (c1, c2) :: rem -> if c <= c2 then c >= c1 else mem c rem
|
||||
|
||||
(****)
|
||||
|
||||
type hash = int
|
||||
|
||||
let rec hash_rec = function
|
||||
| [] -> 0
|
||||
| (i, j)::r -> i + 13 * j + 257 * hash_rec r
|
||||
let hash l = (hash_rec l) land 0x3FFFFFFF
|
||||
|
||||
(****)
|
||||
|
||||
let print_one ch (c1, c2) =
|
||||
if c1 = c2 then
|
||||
Format.fprintf ch "%d" c1
|
||||
else
|
||||
Format.fprintf ch "%d-%d" c1 c2
|
||||
|
||||
let pp = Fmt.list print_one
|
||||
|
||||
let rec iter t ~f =
|
||||
match t with
|
||||
| [] -> ()
|
||||
| (x, y)::xs ->
|
||||
f x y;
|
||||
iter xs ~f
|
||||
|
||||
let one_char = function
|
||||
| [i, j] when i = j -> Some i
|
||||
| _ -> None
|
||||
|
||||
|
||||
module CSetMap = Map.Make (struct
|
||||
type t = int * (int * int) list
|
||||
let compare (i, u) (j, v) =
|
||||
let c = compare i j in
|
||||
if c <> 0
|
||||
then c
|
||||
else compare u v
|
||||
end)
|
||||
|
||||
let fold_right t ~init ~f = List.fold_right f t init
|
||||
|
||||
let csingle c = single (Char.code c)
|
||||
|
||||
let cany = [0, 255]
|
||||
|
||||
let is_empty = function
|
||||
| [] -> true
|
||||
| _ -> false
|
||||
|
||||
let rec prepend s x l =
|
||||
match s, l with
|
||||
| [], _ -> l
|
||||
| _r, [] -> []
|
||||
| (_c, c') :: r, ([d, _d'], _x') :: _r' when c' < d -> prepend r x l
|
||||
| (c, c') :: r, ([d, d'], x') :: r' ->
|
||||
if c <= d then begin
|
||||
if c' < d'
|
||||
then ([d, c'], x @ x') :: prepend r x (([c' + 1, d'], x') :: r')
|
||||
else ([d, d'], x @ x') :: prepend s x r'
|
||||
end else begin
|
||||
if c > d'
|
||||
then ([d, d'], x') :: prepend s x r'
|
||||
else ([d, c - 1], x') :: prepend s x (([c, d'], x') :: r')
|
||||
end
|
||||
| _ -> assert false
|
||||
|
||||
let pick = function
|
||||
| [] -> invalid_arg "Re_cset.pick"
|
||||
| (x, _)::_ -> x
|
||||
63
unikernel/duniverse/dune_/vendor/re/src/cset.mli
vendored
Normal file
63
unikernel/duniverse/dune_/vendor/re/src/cset.mli
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(* Character sets, represented as sorted list of intervals *)
|
||||
|
||||
type c = int
|
||||
type t
|
||||
|
||||
val iter : t -> f:(c -> c -> unit) -> unit
|
||||
|
||||
val union : t -> t -> t
|
||||
val inter : t -> t -> t
|
||||
val diff : t -> t -> t
|
||||
val offset : int -> t -> t
|
||||
|
||||
val empty : t
|
||||
val single : c -> t
|
||||
val seq : c -> c -> t
|
||||
val add : c -> t -> t
|
||||
|
||||
val mem : c -> t -> bool
|
||||
|
||||
type hash
|
||||
val hash : t -> hash
|
||||
|
||||
val pp : Format.formatter -> t -> unit
|
||||
|
||||
val one_char : t -> c option
|
||||
|
||||
val fold_right : t -> init:'acc -> f:(c * c -> 'acc -> 'acc) -> 'acc
|
||||
|
||||
val hash_rec : t -> int
|
||||
|
||||
module CSetMap : Map.S with type key = int * t
|
||||
|
||||
val cany : t
|
||||
|
||||
val csingle : char -> t
|
||||
|
||||
val is_empty : t -> bool
|
||||
|
||||
val prepend : t -> 'a list -> (t * 'a list) list -> (t * 'a list) list
|
||||
|
||||
val pick : t -> c
|
||||
4
unikernel/duniverse/dune_/vendor/re/src/dune
vendored
Normal file
4
unikernel/duniverse/dune_/vendor/re/src/dune
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
(library
|
||||
(name dune_re)
|
||||
(public_name dune-private-libs.dune_re)
|
||||
(synopsis "Internal Dune library, do not use!"))
|
||||
1
unikernel/duniverse/dune_/vendor/re/src/dune_re.ml
vendored
Normal file
1
unikernel/duniverse/dune_/vendor/re/src/dune_re.ml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
include Re
|
||||
124
unikernel/duniverse/dune_/vendor/re/src/emacs.ml
vendored
Normal file
124
unikernel/duniverse/dune_/vendor/re/src/emacs.ml
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
module Re = Core
|
||||
|
||||
exception Parse_error
|
||||
exception Not_supported
|
||||
|
||||
let parse s =
|
||||
let i = ref 0 in
|
||||
let l = String.length s in
|
||||
let eos () = !i = l in
|
||||
let test c = not (eos ()) && s.[!i] = c in
|
||||
let test2 c c' = !i + 1 < l && s.[!i] = c && s.[!i + 1] = c' in
|
||||
let accept c = let r = test c in if r then incr i; r in
|
||||
let accept2 c c' = let r = test2 c c' in if r then i := !i + 2; r in
|
||||
let get () = let r = s.[!i] in incr i; r in
|
||||
|
||||
let rec regexp () = regexp' (branch ())
|
||||
and regexp' left =
|
||||
if accept2 '\\' '|' then regexp' (Re.alt [left; branch ()]) else left
|
||||
and branch () = branch' []
|
||||
and branch' left =
|
||||
if eos () || test2 '\\' '|' || test2 '\\' ')' then Re.seq (List.rev left)
|
||||
else branch' (piece () :: left)
|
||||
and piece () =
|
||||
let r = atom () in
|
||||
if accept '*' then Re.rep r else
|
||||
if accept '+' then Re.rep1 r else
|
||||
if accept '?' then Re.opt r else
|
||||
r
|
||||
and atom () =
|
||||
if accept '.' then begin
|
||||
Re.notnl
|
||||
end else if accept '^' then begin
|
||||
Re.bol
|
||||
end else if accept '$' then begin
|
||||
Re.eol
|
||||
end else if accept '[' then begin
|
||||
if accept '^' then
|
||||
Re.compl (bracket [])
|
||||
else
|
||||
Re.alt (bracket [])
|
||||
end else if accept '\\' then begin
|
||||
if accept '(' then begin
|
||||
let r = regexp () in
|
||||
if not (accept2 '\\' ')') then raise Parse_error;
|
||||
Re.group r
|
||||
end else if accept '`' then
|
||||
Re.bos
|
||||
else if accept '\'' then
|
||||
Re.eos
|
||||
else if accept '=' then
|
||||
Re.start
|
||||
else if accept 'b' then
|
||||
Re.alt [Re.bow; Re.eow]
|
||||
else if accept 'B' then
|
||||
Re.not_boundary
|
||||
else if accept '<' then
|
||||
Re.bow
|
||||
else if accept '>' then
|
||||
Re.eow
|
||||
else if accept 'w' then
|
||||
Re.alt [Re.alnum; Re.char '_']
|
||||
else if accept 'W' then
|
||||
Re.compl [Re.alnum; Re.char '_']
|
||||
else begin
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'*' | '+' | '?' | '[' | ']' | '.' | '^' | '$' | '\\' as c ->
|
||||
Re.char c
|
||||
| '0' .. '9' ->
|
||||
raise Not_supported
|
||||
| _ ->
|
||||
raise Parse_error
|
||||
end
|
||||
end else begin
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'*' | '+' | '?' -> raise Parse_error
|
||||
| c -> Re.char c
|
||||
end
|
||||
and bracket s =
|
||||
if s <> [] && accept ']' then s else begin
|
||||
let c = char () in
|
||||
if accept '-' then begin
|
||||
if accept ']' then Re.char c :: Re.char '-' :: s else begin
|
||||
let c' = char () in
|
||||
bracket (Re.rg c c' :: s)
|
||||
end
|
||||
end else
|
||||
bracket (Re.char c :: s)
|
||||
end
|
||||
and char () =
|
||||
if eos () then raise Parse_error;
|
||||
get ()
|
||||
in
|
||||
let res = regexp () in
|
||||
if not (eos ()) then raise Parse_error;
|
||||
res
|
||||
|
||||
let re ?(case = true) s = let r = parse s in if case then r else Re.no_case r
|
||||
|
||||
let compile = Re.compile
|
||||
let compile_pat ?(case = true) s = compile (re ~case s)
|
||||
37
unikernel/duniverse/dune_/vendor/re/src/emacs.mli
vendored
Normal file
37
unikernel/duniverse/dune_/vendor/re/src/emacs.mli
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(** Emacs-style regular expressions *)
|
||||
|
||||
exception Parse_error
|
||||
exception Not_supported
|
||||
(** Errors that can be raised during the parsing of the regular expression *)
|
||||
|
||||
val re : ?case:bool -> string -> Core.t
|
||||
(** Parsing of an Emacs-style regular expression *)
|
||||
|
||||
val compile : Core.t -> Core.re
|
||||
(** Regular expression compilation *)
|
||||
|
||||
val compile_pat : ?case:bool -> string -> Core.re
|
||||
(** Same as [Core.compile] *)
|
||||
|
||||
35
unikernel/duniverse/dune_/vendor/re/src/fmt.ml
vendored
Normal file
35
unikernel/duniverse/dune_/vendor/re/src/fmt.ml
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
(** Very small tooling for format printers. *)
|
||||
|
||||
include Format
|
||||
|
||||
type 'a t = Format.formatter -> 'a -> unit
|
||||
|
||||
let list = pp_print_list
|
||||
let str = pp_print_string
|
||||
let sexp fmt s pp x = fprintf fmt "@[<3>(%s@ %a)@]" s pp x
|
||||
let pair pp1 pp2 fmt (v1,v2) =
|
||||
pp1 fmt v1; pp_print_space fmt () ; pp2 fmt v2
|
||||
let triple pp1 pp2 pp3 fmt (v1, v2, v3) =
|
||||
pp1 fmt v1; pp_print_space fmt () ;
|
||||
pp2 fmt v2; pp_print_space fmt () ;
|
||||
pp3 fmt v3
|
||||
let int = pp_print_int
|
||||
let optint fmt = function
|
||||
| None -> ()
|
||||
| Some i -> fprintf fmt "@ %d" i
|
||||
|
||||
let quote fmt s = Format.fprintf fmt "\"%s\"" s
|
||||
|
||||
let pp_olist pp_elem fmt =
|
||||
Format.fprintf fmt "@[<3>[@ %a@ ]@]"
|
||||
(pp_print_list
|
||||
~pp_sep:(fun fmt () -> fprintf fmt ";@ ")
|
||||
pp_elem)
|
||||
|
||||
let pp_str_list = pp_olist quote
|
||||
|
||||
let to_to_string pp x =
|
||||
let b = Buffer.create 16 in
|
||||
let fmt = Format.formatter_of_buffer b in
|
||||
pp fmt x;
|
||||
Buffer.contents b
|
||||
352
unikernel/duniverse/dune_/vendor/re/src/glob.ml
vendored
Normal file
352
unikernel/duniverse/dune_/vendor/re/src/glob.ml
vendored
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
module Re = Core
|
||||
|
||||
exception Parse_error
|
||||
|
||||
type enclosed =
|
||||
| Char of char
|
||||
| Range of char * char
|
||||
|
||||
type piece =
|
||||
| Exactly of char
|
||||
| Any_of of enclosed list
|
||||
| Any_but of enclosed list
|
||||
| One
|
||||
| Many
|
||||
| ManyMany
|
||||
|
||||
type t = piece list
|
||||
|
||||
let of_string ~double_asterisk s : t =
|
||||
let i = ref 0 in
|
||||
let l = String.length s in
|
||||
let eos () = !i = l in
|
||||
let read c =
|
||||
let r = not (eos ()) && s.[!i] = c in
|
||||
if r then incr i;
|
||||
r
|
||||
in
|
||||
|
||||
(**
|
||||
[read_ahead pattern] will attempt to read [pattern] and will return [true] if it was successful.
|
||||
If it fails, it will return [false] and not increment the read index.
|
||||
*)
|
||||
let read_ahead pattern =
|
||||
let pattern_len = String.length pattern in
|
||||
(* if the pattern we are looking for exeeds the remaining length of s, return false immediately *)
|
||||
if !i + pattern_len >= l then
|
||||
false
|
||||
else
|
||||
try
|
||||
for j = 0 to pattern_len - 1 do
|
||||
let found = not (eos ()) && s.[!i + j] = pattern.[j] in
|
||||
if not found then raise_notrace Exit;
|
||||
done;
|
||||
i := !i + pattern_len;
|
||||
true
|
||||
with | Exit -> false
|
||||
in
|
||||
|
||||
let char () =
|
||||
ignore (read '\\' : bool);
|
||||
if eos () then raise Parse_error;
|
||||
let r = s.[!i] in
|
||||
incr i;
|
||||
r
|
||||
in
|
||||
|
||||
let enclosed () : enclosed list =
|
||||
let rec loop s =
|
||||
(* This returns the list in reverse order, but order isn't important anyway *)
|
||||
if s <> [] && read ']'
|
||||
then s
|
||||
else
|
||||
let c = char () in
|
||||
if not (read '-')
|
||||
then loop (Char c :: s)
|
||||
else if read ']'
|
||||
then Char c :: Char '-' :: s
|
||||
else
|
||||
let c' = char () in
|
||||
loop (Range (c, c') :: s)
|
||||
in
|
||||
loop []
|
||||
in
|
||||
|
||||
let piece () =
|
||||
if double_asterisk && read_ahead "/**" && not (eos ())
|
||||
then ManyMany
|
||||
else if read '*'
|
||||
then if double_asterisk && read '*'
|
||||
then ManyMany
|
||||
else Many
|
||||
else if read '?'
|
||||
then One
|
||||
else if not (read '[')
|
||||
then Exactly (char ())
|
||||
else if read '^' || read '!'
|
||||
then Any_but (enclosed ())
|
||||
else Any_of (enclosed ())
|
||||
in
|
||||
|
||||
let rec loop pieces =
|
||||
if eos ()
|
||||
then List.rev pieces
|
||||
else loop (piece () :: pieces)
|
||||
in
|
||||
|
||||
loop []
|
||||
|
||||
let mul l l' =
|
||||
List.flatten (List.map (fun s -> List.map (fun s' -> s ^ s') l') l)
|
||||
|
||||
let explode str =
|
||||
let l = String.length str in
|
||||
let rec expl inner s i acc beg =
|
||||
if i >= l then begin
|
||||
if inner then raise Parse_error;
|
||||
(mul beg [String.sub str s (i - s)], i)
|
||||
end else
|
||||
match str.[i] with
|
||||
| '\\' -> expl inner s (i + 2) acc beg
|
||||
| '{' ->
|
||||
let (t, i') = expl true (i + 1) (i + 1) [] [""] in
|
||||
expl inner i' i' acc
|
||||
(mul beg (mul [String.sub str s (i - s)] t))
|
||||
| ',' when inner ->
|
||||
expl inner (i + 1) (i + 1)
|
||||
(mul beg [String.sub str s (i - s)] @ acc) [""]
|
||||
| '}' when inner ->
|
||||
(mul beg [String.sub str s (i - s)] @ acc, i + 1)
|
||||
| _ ->
|
||||
expl inner s (i + 1) acc beg
|
||||
in
|
||||
List.rev (fst (expl false 0 0 [] [""]))
|
||||
|
||||
module State = struct
|
||||
type t = {
|
||||
re_pieces : Re.t list; (* last piece at head of list. *)
|
||||
remaining : piece list; (* last piece at tail of list. *)
|
||||
am_at_start_of_pattern : bool; (* true at start of pattern *)
|
||||
am_at_start_of_component : bool; (* true at start of pattern or immediately
|
||||
after '/' *)
|
||||
pathname : bool;
|
||||
match_backslashes : bool;
|
||||
period : bool;
|
||||
}
|
||||
|
||||
let create ~period ~pathname ~match_backslashes remaining =
|
||||
{
|
||||
re_pieces = [];
|
||||
am_at_start_of_pattern = true;
|
||||
am_at_start_of_component = true;
|
||||
pathname;
|
||||
match_backslashes;
|
||||
period;
|
||||
remaining;
|
||||
}
|
||||
|
||||
let explicit_period t =
|
||||
t.period && (
|
||||
t.am_at_start_of_pattern ||
|
||||
(t.am_at_start_of_component && t.pathname)
|
||||
)
|
||||
|
||||
let explicit_slash t = t.pathname
|
||||
|
||||
let slashes t =
|
||||
if t.match_backslashes then ['/'; '\\'] else ['/']
|
||||
|
||||
let append ?(am_at_start_of_component=false) t piece =
|
||||
{ t with
|
||||
re_pieces = piece :: t.re_pieces;
|
||||
am_at_start_of_pattern = false;
|
||||
am_at_start_of_component;
|
||||
}
|
||||
|
||||
let to_re t = Re.seq (List.rev t.re_pieces)
|
||||
|
||||
let next t =
|
||||
match t.remaining with
|
||||
| [] -> None
|
||||
| piece :: remaining -> Some (piece, { t with remaining })
|
||||
end
|
||||
|
||||
let one ~explicit_slash ~slashes ~explicit_period =
|
||||
Re.compl (
|
||||
List.concat [
|
||||
if explicit_slash then List.map Re.char slashes else [];
|
||||
if explicit_period then [Re.char '.'] else [];
|
||||
]
|
||||
)
|
||||
|
||||
let enclosed enclosed =
|
||||
match enclosed with
|
||||
| Char c -> Re.char c
|
||||
| Range (low, high) -> Re.rg low high
|
||||
|
||||
let enclosed_set ~explicit_slash ~slashes ~explicit_period kind set =
|
||||
let set = List.map enclosed set in
|
||||
let enclosure =
|
||||
match kind with
|
||||
| `Any_of -> Re.alt set
|
||||
| `Any_but -> Re.compl set
|
||||
in
|
||||
Re.inter [enclosure; one ~explicit_slash ~slashes ~explicit_period]
|
||||
|
||||
let exactly state c =
|
||||
let slashes = State.slashes state in
|
||||
let am_at_start_of_component = List.mem c slashes in
|
||||
let chars = if am_at_start_of_component then slashes else [c] in
|
||||
State.append state (Re.alt (List.map Re.char chars)) ~am_at_start_of_component
|
||||
|
||||
let many_many state =
|
||||
let explicit_period = state.State.period && state.State.pathname in
|
||||
let first_explicit_period = State.explicit_period state in
|
||||
let slashes = State.slashes state in
|
||||
let match_component ~explicit_period =
|
||||
Re.seq [
|
||||
one ~explicit_slash:true ~slashes ~explicit_period;
|
||||
Re.rep (one ~explicit_slash:true ~slashes ~explicit_period:false);
|
||||
]
|
||||
in
|
||||
(* We must match components individually when [period] flag is set,
|
||||
making sure to not match ["foo/.bar"]. *)
|
||||
State.append state (
|
||||
Re.seq [
|
||||
Re.opt (match_component ~explicit_period:first_explicit_period);
|
||||
Re.rep (
|
||||
Re.seq [
|
||||
Re.alt (List.map Re.char slashes);
|
||||
Re.opt (match_component ~explicit_period);
|
||||
]
|
||||
);
|
||||
])
|
||||
|
||||
let many (state : State.t) =
|
||||
let explicit_slash = State.explicit_slash state in
|
||||
let explicit_period = State.explicit_period state in
|
||||
let slashes = State.slashes state in
|
||||
(* Whether we must explicitly match period depends on the surrounding characters, but
|
||||
slashes are easy to explicit match. This conditional splits out some simple cases.
|
||||
*)
|
||||
if not explicit_period then begin
|
||||
State.append state (Re.rep (one ~explicit_slash ~slashes ~explicit_period))
|
||||
end else if not explicit_slash then begin
|
||||
(* In this state, we explicitly match periods only at the very beginning *)
|
||||
State.append state (Re.opt (
|
||||
Re.seq [
|
||||
one ~explicit_slash:false ~slashes ~explicit_period;
|
||||
Re.rep (one ~explicit_slash:false ~slashes ~explicit_period:false);
|
||||
]
|
||||
))
|
||||
end else begin
|
||||
let not_empty =
|
||||
Re.seq [
|
||||
one ~explicit_slash:true ~slashes ~explicit_period:true;
|
||||
Re.rep (one ~explicit_slash:true ~slashes ~explicit_period:false);
|
||||
]
|
||||
in
|
||||
(* [maybe_empty] is the default translation of Many, except in some special cases.
|
||||
*)
|
||||
let maybe_empty = Re.opt not_empty in
|
||||
let enclosed_set state kind set =
|
||||
State.append state (Re.alt [
|
||||
enclosed_set kind set ~explicit_slash:true ~slashes ~explicit_period:true;
|
||||
Re.seq [
|
||||
not_empty;
|
||||
(* Since [not_empty] matched, subsequent dots are not leading. *)
|
||||
enclosed_set kind set ~explicit_slash:true ~slashes ~explicit_period:false;
|
||||
];
|
||||
])
|
||||
in
|
||||
let rec lookahead state =
|
||||
match State.next state with
|
||||
| None -> State.append state maybe_empty
|
||||
(* glob ** === glob * . *)
|
||||
| Some (Many, state) -> lookahead state
|
||||
| Some (Exactly c, state) ->
|
||||
let state =
|
||||
State.append state
|
||||
(if c = '.'
|
||||
then not_empty
|
||||
else maybe_empty)
|
||||
in
|
||||
exactly state c
|
||||
(* glob *? === glob ?* *)
|
||||
| Some (One, state) -> State.append state not_empty
|
||||
| Some (Any_of enclosed, state) -> enclosed_set state `Any_of enclosed
|
||||
| Some (Any_but enclosed, state) -> enclosed_set state `Any_but enclosed
|
||||
(* * then ** === ** *)
|
||||
| Some (ManyMany, state) -> many_many state
|
||||
in
|
||||
lookahead state
|
||||
end
|
||||
|
||||
let piece state piece =
|
||||
let explicit_slash = State.explicit_slash state in
|
||||
let explicit_period = State.explicit_period state in
|
||||
let slashes = State.slashes state in
|
||||
match piece with
|
||||
| One -> State.append state (one ~explicit_slash ~slashes ~explicit_period)
|
||||
| Many -> many state
|
||||
| Any_of enclosed ->
|
||||
State.append state (enclosed_set `Any_of ~explicit_slash ~slashes ~explicit_period enclosed)
|
||||
| Any_but enclosed ->
|
||||
State.append state (enclosed_set `Any_but ~explicit_slash ~slashes ~explicit_period enclosed)
|
||||
| Exactly c -> exactly state c
|
||||
| ManyMany -> many_many state
|
||||
|
||||
let glob ~pathname ~match_backslashes ~period glob =
|
||||
let rec loop state =
|
||||
match State.next state with
|
||||
| None -> State.to_re state
|
||||
| Some (p, state) -> loop (piece state p)
|
||||
in
|
||||
loop (State.create ~pathname ~match_backslashes ~period glob)
|
||||
|
||||
let glob
|
||||
?(anchored = false)
|
||||
?(pathname = true)
|
||||
?(match_backslashes = false)
|
||||
?(period = true)
|
||||
?(expand_braces = false)
|
||||
?(double_asterisk = true)
|
||||
s
|
||||
=
|
||||
let to_re s =
|
||||
let re = glob ~pathname ~match_backslashes ~period (of_string ~double_asterisk s) in
|
||||
if anchored
|
||||
then Re.whole_string re
|
||||
else re
|
||||
in
|
||||
if expand_braces
|
||||
then Re.alt (List.map to_re (explode s))
|
||||
else to_re s
|
||||
|
||||
let glob' ?anchored period s = glob ?anchored ~period s
|
||||
|
||||
let globx ?anchored s = glob ?anchored ~expand_braces:true s
|
||||
|
||||
let globx' ?anchored period s = glob ?anchored ~expand_braces:true ~period s
|
||||
88
unikernel/duniverse/dune_/vendor/re/src/glob.mli
vendored
Normal file
88
unikernel/duniverse/dune_/vendor/re/src/glob.mli
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(** Shell-style regular expressions *)
|
||||
|
||||
exception Parse_error
|
||||
|
||||
val glob :
|
||||
?anchored:bool ->
|
||||
?pathname:bool ->
|
||||
?match_backslashes:bool ->
|
||||
?period:bool ->
|
||||
?expand_braces:bool ->
|
||||
?double_asterisk:bool ->
|
||||
string ->
|
||||
Core.t
|
||||
(** Implements the semantics of shells patterns. The returned regular
|
||||
expression is unanchored by default.
|
||||
|
||||
Character '*' matches any sequence of characters and character
|
||||
'?' matches a single character.
|
||||
A sequence '[...]' matches any one of the enclosed characters.
|
||||
A sequence '[^...]' or '[!...]' matches any character *but* the enclosed characters.
|
||||
A backslash escapes the following character. The last character of the string cannot
|
||||
be a backslash.
|
||||
|
||||
[anchored] controls whether the regular expression will only match entire
|
||||
strings. Defaults to false.
|
||||
|
||||
[pathname]: If this flag is set, match a slash in string only with a slash in pattern
|
||||
and not by an asterisk ('*') or a question mark ('?') metacharacter, nor by a bracket
|
||||
expression ('[]') containing a slash. Defaults to true.
|
||||
|
||||
[match_backslashes]: If this flag is set, a forward slash will also match a
|
||||
backslash (useful when globbing Windows paths). Note that a backslash in the
|
||||
pattern will continue to escape the following character. Defaults to
|
||||
[false].
|
||||
|
||||
[period]: If this flag is set, a leading period in string has to be matched exactly by
|
||||
a period in pattern. A period is considered to be leading if it is the first
|
||||
character in string, or if both [pathname] is set and the period immediately follows a
|
||||
slash. Defaults to true.
|
||||
|
||||
If [expand_braces] is true, braced sets will expand into multiple globs,
|
||||
e.g. a\{x,y\}b\{1,2\} matches axb1, axb2, ayb1, ayb2. As specified for bash, brace
|
||||
expansion is purely textual and can be nested. Defaults to false.
|
||||
|
||||
[double_asterisk]: If this flag is set, double asterisks ('**') will match slash
|
||||
characters, even if [pathname] is set. The [period] flag still applies. Default to
|
||||
true. *)
|
||||
|
||||
val glob' : ?anchored:bool -> bool -> string -> Core.t
|
||||
(** Same, but allows to choose whether dots at the beginning of a
|
||||
file name need to be explicitly matched (true) or not (false)
|
||||
|
||||
@deprecated Use [glob ~period].
|
||||
*)
|
||||
|
||||
val globx : ?anchored:bool -> string -> Core.t
|
||||
(** This version of [glob] also recognizes the pattern \{..,..\}
|
||||
|
||||
@deprecated Prefer [glob ~expand_braces:true].
|
||||
*)
|
||||
|
||||
val globx' : ?anchored:bool -> bool -> string -> Core.t
|
||||
(** This version of [glob'] also recognizes the pattern \{..,..\}
|
||||
|
||||
@deprecated Prefer [glob ~expand_braces:true ~period].
|
||||
*)
|
||||
78
unikernel/duniverse/dune_/vendor/re/src/group.ml
vendored
Normal file
78
unikernel/duniverse/dune_/vendor/re/src/group.ml
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
(* Result of a successful match. *)
|
||||
type t =
|
||||
{ s : string
|
||||
; marks : Automata.mark_infos
|
||||
; pmarks : Pmark.Set.t
|
||||
; gpos : int array
|
||||
; gcount : int
|
||||
}
|
||||
|
||||
let offset t i =
|
||||
if 2 * i + 1 >= Array.length t.marks then raise Not_found;
|
||||
let m1 = t.marks.(2 * i) in
|
||||
if m1 = -1 then raise Not_found;
|
||||
let p1 = t.gpos.(m1) in
|
||||
let p2 = t.gpos.(t.marks.(2 * i + 1)) in
|
||||
(p1, p2)
|
||||
|
||||
let get t i =
|
||||
let (p1, p2) = offset t i in
|
||||
String.sub t.s p1 (p2 - p1)
|
||||
|
||||
let start subs i = fst (offset subs i)
|
||||
|
||||
let stop subs i = snd (offset subs i)
|
||||
|
||||
let test t i =
|
||||
if 2 * i >= Array.length t.marks then
|
||||
false
|
||||
else
|
||||
let idx = t.marks.(2 * i) in
|
||||
idx <> -1
|
||||
|
||||
let get_opt t i =
|
||||
if test t i
|
||||
then Some (get t i)
|
||||
else None
|
||||
|
||||
let dummy_offset = (-1, -1)
|
||||
|
||||
let all_offset t =
|
||||
let res = Array.make t.gcount dummy_offset in
|
||||
for i = 0 to Array.length t.marks / 2 - 1 do
|
||||
let m1 = t.marks.(2 * i) in
|
||||
if m1 <> -1 then begin
|
||||
let p1 = t.gpos.(m1) in
|
||||
let p2 = t.gpos.(t.marks.(2 * i + 1)) in
|
||||
res.(i) <- (p1, p2)
|
||||
end
|
||||
done;
|
||||
res
|
||||
|
||||
let dummy_string = ""
|
||||
|
||||
let all t =
|
||||
let res = Array.make t.gcount dummy_string in
|
||||
for i = 0 to Array.length t.marks / 2 - 1 do
|
||||
let m1 = t.marks.(2 * i) in
|
||||
if m1 <> -1 then begin
|
||||
let p1 = t.gpos.(m1) in
|
||||
let p2 = t.gpos.(t.marks.(2 * i + 1)) in
|
||||
res.(i) <- String.sub t.s p1 (p2 - p1)
|
||||
end
|
||||
done;
|
||||
res
|
||||
|
||||
let pp fmt t =
|
||||
let matches =
|
||||
let offsets = all_offset t in
|
||||
let strs = all t in
|
||||
Array.to_list (
|
||||
Array.init (Array.length strs) (fun i -> strs.(i), offsets.(i))
|
||||
) in
|
||||
let open Fmt in
|
||||
let pp_match fmt (str, (start, stop)) =
|
||||
fprintf fmt "@[(%s (%d %d))@]" str start stop in
|
||||
sexp fmt "Group" (list pp_match) matches
|
||||
|
||||
let nb_groups t = t.gcount
|
||||
55
unikernel/duniverse/dune_/vendor/re/src/group.mli
vendored
Normal file
55
unikernel/duniverse/dune_/vendor/re/src/group.mli
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
(* Result of a successful match. *)
|
||||
type t =
|
||||
{ s : string
|
||||
(* Input string. Matched strings are substrings of s *)
|
||||
|
||||
; marks : Automata.mark_infos
|
||||
(* Mapping from group indices to positions in gpos. group i has positions 2*i
|
||||
- 1, 2*i + 1 in gpos. If the group wasn't matched, then its corresponding
|
||||
values in marks will be -1,-1 *)
|
||||
|
||||
; pmarks : Pmark.Set.t
|
||||
(* Marks positions. i.e. those marks created with Re.marks *)
|
||||
|
||||
; gpos : int array
|
||||
(* Group positions. Adjacent elements are (start, stop) of group match.
|
||||
indexed by the values in marks. So group i in an re would be the substring:
|
||||
|
||||
start = t.gpos.(marks.(2*i)) - 1
|
||||
stop = t.gpos.(marks.(2*i + 1)) - 1 *)
|
||||
|
||||
; gcount : int
|
||||
(* Number of groups the regular expression contains. Matched or not *)
|
||||
}
|
||||
|
||||
(** Information about groups in a match. *)
|
||||
|
||||
val get : t -> int -> string
|
||||
(** Raise [Not_found] if the group did not match *)
|
||||
|
||||
val get_opt : t -> int -> string option
|
||||
(** Similar to {!get}, but returns an option instead of using an exception. *)
|
||||
|
||||
val offset : t -> int -> int * int
|
||||
(** Raise [Not_found] if the group did not match *)
|
||||
|
||||
val start : t -> int -> int
|
||||
(** Return the start of the match. Raise [Not_found] if the group did not match. *)
|
||||
|
||||
val stop : t -> int -> int
|
||||
(** Return the end of the match. Raise [Not_found] if the group did not match. *)
|
||||
|
||||
val all : t -> string array
|
||||
(** Return the empty string for each group which did not match *)
|
||||
|
||||
val all_offset : t -> (int * int) array
|
||||
(** Return [(-1,-1)] for each group which did not match *)
|
||||
|
||||
val test : t -> int -> bool
|
||||
(** Test whether a group matched *)
|
||||
|
||||
val nb_groups : t -> int
|
||||
(** Returns the total number of groups defined - matched or not.
|
||||
This function is experimental. *)
|
||||
|
||||
val pp : Format.formatter -> t -> unit
|
||||
140
unikernel/duniverse/dune_/vendor/re/src/pcre.ml
vendored
Normal file
140
unikernel/duniverse/dune_/vendor/re/src/pcre.ml
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
module Re = Core
|
||||
|
||||
exception Parse_error = Perl.Parse_error
|
||||
exception Not_supported = Perl.Not_supported
|
||||
|
||||
type regexp = Re.re
|
||||
|
||||
type flag = [ `CASELESS | `MULTILINE | `ANCHORED | `DOTALL ]
|
||||
|
||||
type split_result =
|
||||
| Text of string
|
||||
| Delim of string
|
||||
| Group of int * string
|
||||
| NoGroup
|
||||
|
||||
type groups = Core.Group.t
|
||||
|
||||
let re ?(flags = []) pat =
|
||||
let opts = List.map (function
|
||||
| `CASELESS -> `Caseless
|
||||
| `MULTILINE -> `Multiline
|
||||
| `ANCHORED -> `Anchored
|
||||
| `DOTALL -> `Dotall
|
||||
) flags in
|
||||
Perl.re ~opts pat
|
||||
|
||||
let regexp ?flags pat = Re.compile (re ?flags pat)
|
||||
|
||||
let extract ~rex s =
|
||||
Re.Group.all (Re.exec rex s)
|
||||
|
||||
let exec ~rex ?pos s =
|
||||
Re.exec rex ?pos s
|
||||
|
||||
let get_substring s i =
|
||||
Re.Group.get s i
|
||||
|
||||
let names rex =
|
||||
Re.group_names rex
|
||||
|> List.map fst
|
||||
|> Array.of_list
|
||||
|
||||
let get_named_substring rex name s =
|
||||
let rec loop = function
|
||||
| [] -> raise Not_found
|
||||
| (n, i) :: rem when n = name ->
|
||||
begin
|
||||
try get_substring s i
|
||||
with Not_found -> loop rem
|
||||
end
|
||||
| _ :: rem -> loop rem
|
||||
in
|
||||
loop (Re.group_names rex)
|
||||
|
||||
let get_substring_ofs s i =
|
||||
Re.Group.offset s i
|
||||
|
||||
let pmatch ~rex s =
|
||||
Re.execp rex s
|
||||
|
||||
let substitute ~rex ~subst str =
|
||||
let b = Buffer.create 1024 in
|
||||
let rec loop pos =
|
||||
if pos >= String.length str then
|
||||
Buffer.contents b
|
||||
else if Re.execp ~pos rex str then (
|
||||
let ss = Re.exec ~pos rex str in
|
||||
let start, fin = Re.Group.offset ss 0 in
|
||||
let pat = Re.Group.get ss 0 in
|
||||
Buffer.add_substring b str pos (start - pos);
|
||||
Buffer.add_string b (subst pat);
|
||||
loop fin
|
||||
) else (
|
||||
Buffer.add_substring b str pos (String.length str - pos);
|
||||
loop (String.length str)
|
||||
)
|
||||
in
|
||||
loop 0
|
||||
|
||||
let split ~rex str =
|
||||
let rec loop accu pos =
|
||||
if pos >= String.length str then
|
||||
List.rev accu
|
||||
else if Re.execp ~pos rex str then (
|
||||
let ss = Re.exec ~pos rex str in
|
||||
let start, fin = Re.Group.offset ss 0 in
|
||||
let s = String.sub str pos (start - pos) in
|
||||
loop (s :: accu) fin
|
||||
) else (
|
||||
let s = String.sub str pos (String.length str - pos) in
|
||||
loop (s :: accu) (String.length str)
|
||||
) in
|
||||
loop [] 0
|
||||
|
||||
(* From PCRE *)
|
||||
let string_unsafe_sub s ofs len =
|
||||
let r = Bytes.create len in
|
||||
Bytes.unsafe_blit s ofs r 0 len;
|
||||
Bytes.unsafe_to_string r
|
||||
|
||||
let quote s =
|
||||
let len = String.length s in
|
||||
let buf = Bytes.create (len lsl 1) in
|
||||
let pos = ref 0 in
|
||||
for i = 0 to len - 1 do
|
||||
match String.unsafe_get s i with
|
||||
| '\\' | '^' | '$' | '.' | '[' | '|'
|
||||
| '(' | ')' | '?' | '*' | '+' | '{' as c ->
|
||||
Bytes.unsafe_set buf !pos '\\';
|
||||
incr pos;
|
||||
Bytes.unsafe_set buf !pos c; incr pos
|
||||
| c -> Bytes.unsafe_set buf !pos c; incr pos
|
||||
done;
|
||||
string_unsafe_sub buf 0 !pos
|
||||
|
||||
let full_split ?(max=0) ~rex s =
|
||||
if String.length s = 0 then []
|
||||
else if max = 1 then [Text s]
|
||||
else
|
||||
let results = Re.split_full rex s in
|
||||
let matches =
|
||||
List.map (function
|
||||
| `Text s -> [Text s]
|
||||
| `Delim d ->
|
||||
let matches = Re.Group.all_offset d in
|
||||
let delim = Re.Group.get d 0 in
|
||||
(Delim delim)::(
|
||||
let l = ref [] in
|
||||
for i = 1 to Array.length matches - 1 do
|
||||
l :=
|
||||
(if matches.(i) = (-1, -1)
|
||||
then NoGroup
|
||||
else Group (i, Re.Group.get d i))
|
||||
::(!l)
|
||||
done;
|
||||
List.rev !l)) results in
|
||||
List.concat matches
|
||||
|
||||
|
||||
type substrings = Group.t
|
||||
54
unikernel/duniverse/dune_/vendor/re/src/pcre.mli
vendored
Normal file
54
unikernel/duniverse/dune_/vendor/re/src/pcre.mli
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
exception Parse_error
|
||||
exception Not_supported
|
||||
|
||||
type regexp = Core.re
|
||||
|
||||
type flag = [ `CASELESS | `MULTILINE | `ANCHORED | `DOTALL ]
|
||||
|
||||
type groups = Core.Group.t
|
||||
|
||||
(** Result of a {!Pcre.full_split} *)
|
||||
type split_result =
|
||||
| Text of string (** Text part of splitted string *)
|
||||
| Delim of string (** Delimiter part of splitted string *)
|
||||
| Group of int * string (** Subgroup of matched delimiter (subgroup_nr, subgroup_str) *)
|
||||
| NoGroup (** Unmatched subgroup *)
|
||||
|
||||
val re : ?flags:(flag list) -> string -> Core.t
|
||||
(** [re ~flags s] creates the regexp [s] using the pcre syntax. *)
|
||||
|
||||
val regexp : ?flags:(flag list) -> string -> regexp
|
||||
(** [re ~flags s] compiles the regexp [s] using the pcre syntax. *)
|
||||
|
||||
val extract : rex:regexp -> string -> string array
|
||||
(** [extract ~rex s] executes [rex] on [s] and returns the matching groups. *)
|
||||
|
||||
val exec : rex:regexp -> ?pos:int -> string -> groups
|
||||
(** Equivalent to {!Core.exec}. *)
|
||||
|
||||
val get_substring : groups -> int -> string
|
||||
(** Equivalent to {!Core.Group.get}. *)
|
||||
|
||||
val names : regexp -> string array
|
||||
(** Return the names of named groups. *)
|
||||
|
||||
val get_named_substring : regexp -> string -> groups -> string
|
||||
(** Return the first matched named group, or raise [Not_found]. *)
|
||||
|
||||
val get_substring_ofs : groups -> int -> int * int
|
||||
(** Equivalent to {!Core.Group.offset}. *)
|
||||
|
||||
val pmatch : rex:regexp -> string -> bool
|
||||
(** Equivalent to {!Core.execp}. *)
|
||||
|
||||
val substitute : rex:Core.re -> subst:(string -> string) -> string -> string
|
||||
|
||||
val full_split : ?max:int -> rex:regexp -> string -> split_result list
|
||||
|
||||
val split : rex:regexp -> string -> string list
|
||||
|
||||
val quote : string -> string
|
||||
|
||||
(** {2 Deprecated} *)
|
||||
|
||||
type substrings = Group.t
|
||||
316
unikernel/duniverse/dune_/vendor/re/src/perl.ml
vendored
Normal file
316
unikernel/duniverse/dune_/vendor/re/src/perl.ml
vendored
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
module Re = Core
|
||||
|
||||
exception Parse_error
|
||||
exception Not_supported
|
||||
|
||||
let posix_class_of_string = function
|
||||
| "alpha" -> Re.alpha
|
||||
| "alnum" -> Re.alnum
|
||||
| "ascii" -> Re.ascii
|
||||
| "blank" -> Re.blank
|
||||
| "cntrl" -> Re.cntrl
|
||||
| "digit" -> Re.digit
|
||||
| "lower" -> Re.lower
|
||||
| "print" -> Re.print
|
||||
| "space" -> Re.space
|
||||
| "upper" -> Re.upper
|
||||
| "word" -> Re.wordc
|
||||
| "punct" -> Re.punct
|
||||
| "graph" -> Re.graph
|
||||
| "xdigit" -> Re.xdigit
|
||||
| class_ -> invalid_arg ("Invalid pcre class: " ^ class_)
|
||||
|
||||
let posix_class_strings =
|
||||
[ "alpha" ; "alnum" ; "ascii"
|
||||
; "blank" ; "cntrl" ; "digit"
|
||||
; "lower" ; "print" ; "space"
|
||||
; "upper" ; "word" ; "punct"
|
||||
; "graph" ; "xdigit" ]
|
||||
|
||||
let parse multiline dollar_endonly dotall ungreedy s =
|
||||
let i = ref 0 in
|
||||
let l = String.length s in
|
||||
let eos () = !i = l in
|
||||
let test c = not (eos ()) && s.[!i] = c in
|
||||
let accept c = let r = test c in if r then incr i; r in
|
||||
let accept_s s' =
|
||||
let len = String.length s' in
|
||||
try
|
||||
for j = 0 to len - 1 do
|
||||
try if s'.[j] <> s.[!i + j] then raise Exit
|
||||
with _ -> raise Exit
|
||||
done;
|
||||
i := !i + len;
|
||||
true
|
||||
with Exit -> false in
|
||||
let get () = let r = s.[!i] in incr i; r in
|
||||
let unget () = decr i in
|
||||
let greedy_mod r =
|
||||
let gr = accept '?' in
|
||||
let gr = if ungreedy then not gr else gr in
|
||||
if gr then Re.non_greedy r else Re.greedy r
|
||||
in
|
||||
let rec regexp () = regexp' (branch ())
|
||||
and regexp' left =
|
||||
if accept '|' then regexp' (Re.alt [left; branch ()]) else left
|
||||
and branch () = branch' []
|
||||
and branch' left =
|
||||
if eos () || test '|' || test ')' then Re.seq (List.rev left)
|
||||
else branch' (piece () :: left)
|
||||
and piece () =
|
||||
let r = atom () in
|
||||
if accept '*' then greedy_mod (Re.rep r) else
|
||||
if accept '+' then greedy_mod (Re.rep1 r) else
|
||||
if accept '?' then greedy_mod (Re.opt r) else
|
||||
if accept '{' then
|
||||
match integer () with
|
||||
Some i ->
|
||||
let j = if accept ',' then integer () else Some i in
|
||||
if not (accept '}') then raise Parse_error;
|
||||
begin match j with
|
||||
Some j when j < i -> raise Parse_error | _ -> ()
|
||||
end;
|
||||
greedy_mod (Re.repn r i j)
|
||||
| None ->
|
||||
unget (); r
|
||||
else
|
||||
r
|
||||
and atom () =
|
||||
if accept '.' then begin
|
||||
if dotall then Re.any else Re.notnl
|
||||
end else if accept '(' then begin
|
||||
if accept '?' then begin
|
||||
if accept ':' then begin
|
||||
let r = regexp () in
|
||||
if not (accept ')') then raise Parse_error;
|
||||
r
|
||||
end else if accept '#' then begin
|
||||
comment ()
|
||||
end else if accept '<' then begin
|
||||
let name = name () in
|
||||
let r = regexp () in
|
||||
if not (accept ')') then raise Parse_error;
|
||||
Re.group ~name r
|
||||
end else
|
||||
raise Parse_error
|
||||
end else begin
|
||||
let r = regexp () in
|
||||
if not (accept ')') then raise Parse_error;
|
||||
Re.group r
|
||||
end
|
||||
end else
|
||||
if accept '^' then begin
|
||||
if multiline then Re.bol else Re.bos
|
||||
end else if accept '$' then begin
|
||||
if multiline then Re.eol else if dollar_endonly then Re.leol else Re.eos
|
||||
end else if accept '[' then begin
|
||||
if accept '^' then
|
||||
Re.compl (bracket [])
|
||||
else
|
||||
Re.alt (bracket [])
|
||||
end else if accept '\\' then begin
|
||||
(* XXX
|
||||
- Back-references
|
||||
- \cx (control-x), \ddd
|
||||
*)
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'w' ->
|
||||
Re.alt [Re.alnum; Re.char '_']
|
||||
| 'W' ->
|
||||
Re.compl [Re.alnum; Re.char '_']
|
||||
| 's' ->
|
||||
Re.space
|
||||
| 'S' ->
|
||||
Re.compl [Re.space]
|
||||
| 'd' ->
|
||||
Re.digit
|
||||
| 'D' ->
|
||||
Re.compl [Re.digit]
|
||||
| 'b' ->
|
||||
Re.alt [Re.bow; Re.eow]
|
||||
| 'B' ->
|
||||
Re.not_boundary
|
||||
| 'A' ->
|
||||
Re.bos
|
||||
| 'Z' ->
|
||||
Re.leol
|
||||
| 'z' ->
|
||||
Re.eos
|
||||
| 'G' ->
|
||||
Re.start
|
||||
| 'e' ->
|
||||
Re.char '\x1b'
|
||||
| 'f' ->
|
||||
Re.char '\x0c'
|
||||
| 'n' ->
|
||||
Re.char '\n'
|
||||
| 'r' ->
|
||||
Re.char '\r'
|
||||
| 't' ->
|
||||
Re.char '\t'
|
||||
| 'x' ->
|
||||
let c1 = hexdigit () in
|
||||
let c2 = hexdigit () in
|
||||
let code = c1 * 16 + c2 in
|
||||
Re.char (char_of_int code)
|
||||
| 'a'..'z' | 'A'..'Z' ->
|
||||
raise Parse_error
|
||||
| '0'..'9' ->
|
||||
raise Not_supported
|
||||
| c ->
|
||||
Re.char c
|
||||
end else begin
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'*' | '+' | '?' | '{' | '\\' -> raise Parse_error
|
||||
| c -> Re.char c
|
||||
end
|
||||
and hexdigit () =
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'0'..'9' as d -> Char.code d - Char.code '0'
|
||||
| 'a'..'f' as d -> Char.code d - Char.code 'a' + 10
|
||||
| 'A'..'F' as d -> Char.code d - Char.code 'A' + 10
|
||||
| _ -> raise Parse_error
|
||||
and integer () =
|
||||
if eos () then None else
|
||||
match get () with
|
||||
'0'..'9' as d -> integer' (Char.code d - Char.code '0')
|
||||
| _ -> unget (); None
|
||||
and integer' i =
|
||||
if eos () then Some i else
|
||||
match get () with
|
||||
'0'..'9' as d ->
|
||||
let i' = 10 * i + (Char.code d - Char.code '0') in
|
||||
if i' < i then raise Parse_error;
|
||||
integer' i'
|
||||
| _ ->
|
||||
unget (); Some i
|
||||
and name () =
|
||||
if eos () then raise Parse_error else
|
||||
match get () with
|
||||
('_' | 'a'..'z' | 'A'..'Z') as c ->
|
||||
let b = Buffer.create 32 in
|
||||
Buffer.add_char b c;
|
||||
name' b
|
||||
| _ -> raise Parse_error
|
||||
and name' b =
|
||||
if eos () then raise Parse_error else
|
||||
match get () with
|
||||
('_' | 'a'..'z' | 'A'..'Z' | '0'..'9') as c ->
|
||||
Buffer.add_char b c;
|
||||
name' b
|
||||
| '>' -> Buffer.contents b
|
||||
| _ -> raise Parse_error
|
||||
and bracket s =
|
||||
if s <> [] && accept ']' then s else begin
|
||||
match char () with
|
||||
| `Char c ->
|
||||
if accept '-' then begin
|
||||
if accept ']' then Re.char c :: Re.char '-' :: s else begin
|
||||
match char () with
|
||||
`Char c' ->
|
||||
bracket (Re.rg c c' :: s)
|
||||
| `Set st' ->
|
||||
bracket (Re.char c :: Re.char '-' :: st' :: s)
|
||||
end
|
||||
end else
|
||||
bracket (Re.char c :: s)
|
||||
| `Set st -> bracket (st :: s)
|
||||
end
|
||||
and char () =
|
||||
if eos () then raise Parse_error;
|
||||
let c = get () in
|
||||
if c = '[' then begin
|
||||
if accept '=' then raise Not_supported;
|
||||
if accept ':' then
|
||||
let compl = accept '^' in
|
||||
let cls =
|
||||
try List.find accept_s posix_class_strings
|
||||
with Not_found -> raise Parse_error in
|
||||
if not (accept_s ":]") then raise Parse_error;
|
||||
let re =
|
||||
let posix_class = posix_class_of_string cls in
|
||||
if compl then Re.compl [posix_class] else posix_class in
|
||||
`Set (re)
|
||||
else if accept '.' then begin
|
||||
if eos () then raise Parse_error;
|
||||
let c = get () in
|
||||
if not (accept '.') then raise Not_supported;
|
||||
if not (accept ']') then raise Parse_error;
|
||||
`Char c
|
||||
end else
|
||||
`Char c
|
||||
end else if c = '\\' then begin
|
||||
if eos () then raise Parse_error;
|
||||
let c = get () in
|
||||
(* XXX
|
||||
\127, ...
|
||||
*)
|
||||
match c with
|
||||
'b' -> `Char '\008'
|
||||
| 'n' -> `Char '\n' (*XXX*)
|
||||
| 'r' -> `Char '\r' (*XXX*)
|
||||
| 't' -> `Char '\t' (*XXX*)
|
||||
| 'w' -> `Set (Re.alt [Re.alnum; Re.char '_'])
|
||||
| 'W' -> `Set (Re.compl [Re.alnum; Re.char '_'])
|
||||
| 's' -> `Set (Re.space)
|
||||
| 'S' -> `Set (Re.compl [Re.space])
|
||||
| 'd' -> `Set (Re.digit)
|
||||
| 'D' -> `Set (Re.compl [Re.digit])
|
||||
| 'a'..'z' | 'A'..'Z' ->
|
||||
raise Parse_error
|
||||
| '0'..'9' ->
|
||||
raise Not_supported
|
||||
| _ ->
|
||||
`Char c
|
||||
end else
|
||||
`Char c
|
||||
and comment () =
|
||||
if eos () then raise Parse_error;
|
||||
if accept ')' then Re.epsilon else begin incr i; comment () end
|
||||
in
|
||||
let res = regexp () in
|
||||
if not (eos ()) then raise Parse_error;
|
||||
res
|
||||
|
||||
type opt =
|
||||
[ `Ungreedy | `Dotall | `Dollar_endonly
|
||||
| `Multiline | `Anchored | `Caseless ]
|
||||
|
||||
let re ?(opts = []) s =
|
||||
let r =
|
||||
parse
|
||||
(List.memq `Multiline opts) (List.memq `Dollar_endonly opts)
|
||||
(List.memq `Dotall opts) (List.memq `Ungreedy opts)
|
||||
s
|
||||
in
|
||||
let r = if List.memq `Anchored opts then Re.seq [Re.start; r] else r in
|
||||
let r = if List.memq `Caseless opts then Re.no_case r else r in
|
||||
r
|
||||
|
||||
let compile = Re.compile
|
||||
let compile_pat ?(opts = []) s = compile (re ~opts s)
|
||||
41
unikernel/duniverse/dune_/vendor/re/src/perl.mli
vendored
Normal file
41
unikernel/duniverse/dune_/vendor/re/src/perl.mli
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(** Perl-style regular expressions *)
|
||||
|
||||
exception Parse_error
|
||||
exception Not_supported
|
||||
(** Errors that can be raised during the parsing of the regular expression *)
|
||||
|
||||
|
||||
type opt =
|
||||
[ `Ungreedy | `Dotall | `Dollar_endonly
|
||||
| `Multiline | `Anchored | `Caseless ]
|
||||
|
||||
val re : ?opts:opt list -> string -> Core.t
|
||||
(** Parsing of a Perl-style regular expression *)
|
||||
|
||||
val compile : Core.t -> Core.re
|
||||
(** (Same as [Re.compile]) *)
|
||||
|
||||
val compile_pat : ?opts:opt list -> string -> Core.re
|
||||
(** Regular expression compilation *)
|
||||
13
unikernel/duniverse/dune_/vendor/re/src/pmark.ml
vendored
Normal file
13
unikernel/duniverse/dune_/vendor/re/src/pmark.ml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
module Pmark = struct
|
||||
type t = int
|
||||
let equal (x : int) (y : int) = x = y
|
||||
let compare (x : int) (y : int) = compare x y
|
||||
let r = ref 0
|
||||
let gen () = incr r ; !r
|
||||
|
||||
let pp = Format.pp_print_int
|
||||
end
|
||||
|
||||
include Pmark
|
||||
module Set = Set.Make(Pmark)
|
||||
8
unikernel/duniverse/dune_/vendor/re/src/pmark.mli
vendored
Normal file
8
unikernel/duniverse/dune_/vendor/re/src/pmark.mli
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
type t = private int
|
||||
val equal : t -> t -> bool
|
||||
val compare : t -> t -> int
|
||||
val gen : unit -> t
|
||||
val pp : Format.formatter -> t -> unit
|
||||
|
||||
module Set : Set.S with type elt = t
|
||||
156
unikernel/duniverse/dune_/vendor/re/src/posix.ml
vendored
Normal file
156
unikernel/duniverse/dune_/vendor/re/src/posix.ml
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(*
|
||||
What we could (should?) do:
|
||||
- a* ==> longest ((shortest (no_group a)* ), a | ()) (!!!)
|
||||
- abc understood as (ab)c
|
||||
- "((a?)|b)" against "ab" should not bind the first subpattern to anything
|
||||
|
||||
Note that it should be possible to handle "(((ab)c)d)e" efficiently
|
||||
*)
|
||||
module Re = Core
|
||||
|
||||
exception Parse_error
|
||||
exception Not_supported
|
||||
|
||||
let parse newline s =
|
||||
let i = ref 0 in
|
||||
let l = String.length s in
|
||||
let eos () = !i = l in
|
||||
let test c = not (eos ()) && s.[!i] = c in
|
||||
let accept c = let r = test c in if r then incr i; r in
|
||||
let get () = let r = s.[!i] in incr i; r in
|
||||
let unget () = decr i in
|
||||
|
||||
let rec regexp () = regexp' (branch ())
|
||||
and regexp' left =
|
||||
if accept '|' then regexp' (Re.alt [left; branch ()]) else left
|
||||
and branch () = branch' []
|
||||
and branch' left =
|
||||
if eos () || test '|' || test ')' then Re.seq (List.rev left)
|
||||
else branch' (piece () :: left)
|
||||
and piece () =
|
||||
let r = atom () in
|
||||
if accept '*' then Re.rep (Re.nest r) else
|
||||
if accept '+' then Re.rep1 (Re.nest r) else
|
||||
if accept '?' then Re.opt r else
|
||||
if accept '{' then
|
||||
match integer () with
|
||||
Some i ->
|
||||
let j = if accept ',' then integer () else Some i in
|
||||
if not (accept '}') then raise Parse_error;
|
||||
begin match j with
|
||||
Some j when j < i -> raise Parse_error | _ -> ()
|
||||
end;
|
||||
Re.repn (Re.nest r) i j
|
||||
| None ->
|
||||
unget (); r
|
||||
else
|
||||
r
|
||||
and atom () =
|
||||
if accept '.' then begin
|
||||
if newline then Re.notnl else Re.any
|
||||
end else if accept '(' then begin
|
||||
let r = regexp () in
|
||||
if not (accept ')') then raise Parse_error;
|
||||
Re.group r
|
||||
end else
|
||||
if accept '^' then begin
|
||||
if newline then Re.bol else Re.bos
|
||||
end else if accept '$' then begin
|
||||
if newline then Re.eol else Re.eos
|
||||
end else if accept '[' then begin
|
||||
if accept '^' then
|
||||
Re.diff (Re.compl (bracket [])) (Re.char '\n')
|
||||
else
|
||||
Re.alt (bracket [])
|
||||
end else
|
||||
if accept '\\' then begin
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'|' | '(' | ')' | '*' | '+' | '?'
|
||||
| '[' | '.' | '^' | '$' | '{' | '\\' as c -> Re.char c
|
||||
| _ -> raise Parse_error
|
||||
end else begin
|
||||
if eos () then raise Parse_error;
|
||||
match get () with
|
||||
'*' | '+' | '?' | '{' | '\\' -> raise Parse_error
|
||||
| c -> Re.char c
|
||||
end
|
||||
and integer () =
|
||||
if eos () then None else
|
||||
match get () with
|
||||
'0'..'9' as d -> integer' (Char.code d - Char.code '0')
|
||||
| _ -> unget (); None
|
||||
and integer' i =
|
||||
if eos () then Some i else
|
||||
match get () with
|
||||
'0'..'9' as d ->
|
||||
let i' = 10 * i + (Char.code d - Char.code '0') in
|
||||
if i' < i then raise Parse_error;
|
||||
integer' i'
|
||||
| _ ->
|
||||
unget (); Some i
|
||||
and bracket s =
|
||||
if s <> [] && accept ']' then s else begin
|
||||
let c = char () in
|
||||
if accept '-' then begin
|
||||
if accept ']' then Re.char c :: Re.char '-' :: s else begin
|
||||
let c' = char () in
|
||||
bracket (Re.rg c c' :: s)
|
||||
end
|
||||
end else
|
||||
bracket (Re.char c :: s)
|
||||
end
|
||||
and char () =
|
||||
if eos () then raise Parse_error;
|
||||
let c = get () in
|
||||
if c = '[' then begin
|
||||
if accept '=' then raise Not_supported
|
||||
else if accept ':' then begin
|
||||
raise Not_supported (*XXX*)
|
||||
end else if accept '.' then begin
|
||||
if eos () then raise Parse_error;
|
||||
let c = get () in
|
||||
if not (accept '.') then raise Not_supported;
|
||||
if not (accept ']') then raise Parse_error;
|
||||
c
|
||||
end else
|
||||
c
|
||||
end else
|
||||
c
|
||||
in
|
||||
let res = regexp () in
|
||||
if not (eos ()) then raise Parse_error;
|
||||
res
|
||||
|
||||
type opt = [`ICase | `NoSub | `Newline]
|
||||
|
||||
let re ?(opts = []) s =
|
||||
let r = parse (List.memq `Newline opts) s in
|
||||
let r = if List.memq `ICase opts then Re.no_case r else r in
|
||||
let r = if List.memq `NoSub opts then Re.no_group r else r in
|
||||
r
|
||||
|
||||
let compile re = Re.compile (Re.longest re)
|
||||
let compile_pat ?(opts = []) s = compile (re ~opts s)
|
||||
98
unikernel/duniverse/dune_/vendor/re/src/posix.mli
vendored
Normal file
98
unikernel/duniverse/dune_/vendor/re/src/posix.mli
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
(*
|
||||
RE - A regular expression library
|
||||
|
||||
Copyright (C) 2001 Jerome Vouillon
|
||||
email: Jerome.Vouillon@pps.jussieu.fr
|
||||
|
||||
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, with
|
||||
linking exception; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
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 GNU
|
||||
Lesser General Public License 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*)
|
||||
|
||||
(**
|
||||
References:
|
||||
- {{: http://www.opengroup.org/onlinepubs/007908799/xbd/re.html} re}
|
||||
- {{: http://www.opengroup.org/onlinepubs/007908799/xsh/regcomp.html} regcomp}
|
||||
|
||||
Example of how to use this module (to parse some IRC logs):
|
||||
|
||||
{[
|
||||
type msg = {
|
||||
time:string;
|
||||
author:string;
|
||||
content:string;
|
||||
}
|
||||
|
||||
let re = Core.compile (Re_posix.re "([^:].*:[^:]*:[^:]{2})<.([^>]+)> (.+)$")
|
||||
|
||||
(* parse a line *)
|
||||
let match_line line =
|
||||
try
|
||||
let substrings = Core.exec re line in
|
||||
let groups = Core.get_all substrings in
|
||||
(* groups can be obtained directly by index within [substrings] *)
|
||||
Some {time=groups.(1); author=groups.(2); content=groups.(3)}
|
||||
with Not_found ->
|
||||
None (* regex didn't match *)
|
||||
]}
|
||||
*)
|
||||
|
||||
(* XXX Character classes *)
|
||||
|
||||
exception Parse_error
|
||||
exception Not_supported
|
||||
(** Errors that can be raised during the parsing of the regular expression *)
|
||||
|
||||
type opt = [`ICase | `NoSub | `Newline]
|
||||
|
||||
val re : ?opts:(opt list) -> string -> Core.t
|
||||
(** Parsing of a Posix extended regular expression *)
|
||||
|
||||
val compile : Core.t -> Core.re
|
||||
(** [compile r] is defined as [Core.compile (Core.longest r)] *)
|
||||
|
||||
val compile_pat : ?opts:(opt list) -> string -> Core.re
|
||||
(** [compile_pat ?opts regex] compiles the Posix extended regular expression [regexp] *)
|
||||
|
||||
(*
|
||||
Deviation from the standard / ambiguities in the standard
|
||||
---------------------------------------------------------
|
||||
We tested the behavior of the Linux library (glibc) and the Solaris
|
||||
library.
|
||||
|
||||
(1) An expression [efg] should be parsed as [(ef)g].
|
||||
All implementations parse it as [e(fg)].
|
||||
(2) When matching the pattern "((a)|b)*" against the string "ab",
|
||||
the sub-expression "((a)|b)" should match "b", and the
|
||||
sub-expression "(a)" should not match anything.
|
||||
In both implementation, the sub-expression "(a)" matches "a".
|
||||
(3) When matching the pattern "(aa?)*" against the string "aaa", it is
|
||||
not clear whether the final match of the sub-expression "(aa?)" is
|
||||
the last "a" (all matches of the sub-expression are successively
|
||||
maximized), or "aa" (the final match is maximized).
|
||||
Both implementations implements the first case.
|
||||
(4) When matching the pattern "((a?)|b)*" against the string "ab",
|
||||
the sub-expression "((a?)|b)" should match the empty string at the
|
||||
end of the string (it is better to match the empty string than to
|
||||
match nothing).
|
||||
In both implementations, this sub-expression matches "b".
|
||||
(Strangely, in the Linux implementation, the sub-expression "(a?)"
|
||||
correctly matches the empty string at the end of the string)
|
||||
|
||||
This library behaves the same way as the other libraries for all
|
||||
points, except for (2) and (4) where it follows the standard.
|
||||
|
||||
The behavior of this library in theses four cases may change in future
|
||||
releases.
|
||||
*)
|
||||
8
unikernel/duniverse/dune_/vendor/re/src/re.ml
vendored
Normal file
8
unikernel/duniverse/dune_/vendor/re/src/re.ml
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
include Core
|
||||
|
||||
module Emacs = Emacs
|
||||
module Glob = Glob
|
||||
module Perl = Perl
|
||||
module Pcre = Pcre
|
||||
module Posix = Posix
|
||||
module Str = Str
|
||||
297
unikernel/duniverse/dune_/vendor/re/src/str.ml
vendored
Normal file
297
unikernel/duniverse/dune_/vendor/re/src/str.ml
vendored
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
(***********************************************************************)
|
||||
(* *)
|
||||
(* Objective Caml *)
|
||||
(* *)
|
||||
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
||||
(* *)
|
||||
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
||||
(* en Automatique. All rights reserved. This file is distributed *)
|
||||
(* under the terms of the GNU Library General Public License, with *)
|
||||
(* linking exception. *)
|
||||
(* *)
|
||||
(***********************************************************************)
|
||||
|
||||
(* Modified by Jerome.Vouillon@pps.jussieu.fr for integration in RE *)
|
||||
|
||||
(* $Id: re_str.ml,v 1.3 2002/07/03 15:47:54 vouillon Exp $ *)
|
||||
|
||||
module Re = Core
|
||||
|
||||
type regexp =
|
||||
{ re: Re.t
|
||||
; mtch: Re.re Lazy.t
|
||||
; srch: Re.re Lazy.t }
|
||||
|
||||
let compile_regexp s c =
|
||||
let re = Emacs.re ~case:(not c) s in
|
||||
{ re
|
||||
; mtch = lazy (Re.compile (Re.seq [Re.start; re]))
|
||||
; srch = lazy (Re.compile re) }
|
||||
|
||||
let state = ref None
|
||||
|
||||
let string_match re s p =
|
||||
try
|
||||
state := Some (Re.exec ~pos:p (Lazy.force re.mtch) s);
|
||||
true
|
||||
with Not_found ->
|
||||
state := None;
|
||||
false
|
||||
|
||||
let string_partial_match re s p =
|
||||
match
|
||||
Re.exec_partial ~pos:p (Lazy.force re.mtch) s
|
||||
with
|
||||
`Full -> string_match re s p
|
||||
| `Partial -> true
|
||||
| `Mismatch -> false
|
||||
|
||||
let search_forward re s p =
|
||||
try
|
||||
let res = Re.exec ~pos:p (Lazy.force re.srch) s in
|
||||
state := Some res;
|
||||
fst (Re.Group.offset res 0)
|
||||
with Not_found ->
|
||||
state := None;
|
||||
raise Not_found
|
||||
|
||||
let rec search_backward re s p =
|
||||
try
|
||||
let res = Re.exec ~pos:p (Lazy.force re.mtch) s in
|
||||
state := Some res;
|
||||
p
|
||||
with Not_found ->
|
||||
state := None;
|
||||
if p = 0 then
|
||||
raise Not_found
|
||||
else
|
||||
search_backward re s (p - 1)
|
||||
|
||||
let valid_group n =
|
||||
n >= 0 && n < 10 && (
|
||||
match !state with
|
||||
| None -> false
|
||||
| Some m -> n < Re.Group.nb_groups m
|
||||
)
|
||||
|
||||
let offset_group i =
|
||||
match !state with
|
||||
| Some m -> Re.Group.offset m i
|
||||
| None -> raise Not_found
|
||||
|
||||
let group_len i =
|
||||
try
|
||||
let (b, e) = offset_group i in
|
||||
e - b
|
||||
with Not_found ->
|
||||
0
|
||||
|
||||
let rec repl_length repl p q len =
|
||||
if p < len then begin
|
||||
if repl.[p] <> '\\' then
|
||||
repl_length repl (p + 1) (q + 1) len
|
||||
else begin
|
||||
let p = p + 1 in
|
||||
if p = len then failwith "Str.replace: illegal backslash sequence";
|
||||
let q =
|
||||
match repl.[p] with
|
||||
| '\\' -> q + 1
|
||||
| '0' .. '9' as c -> q + group_len (Char.code c - Char.code '0')
|
||||
| _ -> q + 2 in
|
||||
repl_length repl (p + 1) q len
|
||||
end
|
||||
end else
|
||||
q
|
||||
|
||||
let rec replace orig repl p res q len =
|
||||
if p < len then begin
|
||||
let c = repl.[p] in
|
||||
if c <> '\\' then begin
|
||||
Bytes.set res q c;
|
||||
replace orig repl (p + 1) res (q + 1) len
|
||||
end else begin
|
||||
match repl.[p + 1] with
|
||||
'\\' ->
|
||||
Bytes.set res q '\\';
|
||||
replace orig repl (p + 2) res (q + 1) len
|
||||
| '0' .. '9' as c ->
|
||||
let d =
|
||||
try
|
||||
let (b, e) = offset_group (Char.code c - Char.code '0') in
|
||||
let d = e - b in
|
||||
if d > 0 then String.blit orig b res q d;
|
||||
d
|
||||
with Not_found ->
|
||||
0
|
||||
in
|
||||
replace orig repl (p + 2) res (q + d) len
|
||||
| c ->
|
||||
Bytes.set res q '\\';
|
||||
Bytes.set res (q + 1) c;
|
||||
replace orig repl (p + 2) res (q + 2) len
|
||||
end
|
||||
end
|
||||
|
||||
let replacement_text repl orig =
|
||||
let len = String.length repl in
|
||||
let res = Bytes.create (repl_length repl 0 0 len) in
|
||||
replace orig repl 0 res 0 (String.length repl);
|
||||
Bytes.unsafe_to_string res
|
||||
|
||||
let quote s =
|
||||
let len = String.length s in
|
||||
let buf = Buffer.create (2 * len) in
|
||||
for i = 0 to len - 1 do
|
||||
match s.[i] with
|
||||
'[' | ']' | '*' | '.' | '\\' | '?' | '+' | '^' | '$' as c ->
|
||||
Buffer.add_char buf '\\';
|
||||
Buffer.add_char buf c
|
||||
| c -> Buffer.add_char buf c
|
||||
done;
|
||||
Buffer.contents buf
|
||||
|
||||
let string_before s n = String.sub s 0 n
|
||||
|
||||
let string_after s n = String.sub s n (String.length s - n)
|
||||
|
||||
let first_chars s n = String.sub s 0 n
|
||||
|
||||
let last_chars s n = String.sub s (String.length s - n) n
|
||||
|
||||
let regexp e = compile_regexp e false
|
||||
|
||||
let regexp_case_fold e = compile_regexp e true
|
||||
|
||||
let regexp_string s = compile_regexp (quote s) false
|
||||
|
||||
let regexp_string_case_fold s = compile_regexp (quote s) true
|
||||
|
||||
let group_beginning n =
|
||||
if not (valid_group n) then invalid_arg "Str.group_beginning";
|
||||
let pos = fst (offset_group n) in
|
||||
if pos = -1 then
|
||||
raise Not_found
|
||||
else
|
||||
pos
|
||||
|
||||
let group_end n =
|
||||
if not (valid_group n) then invalid_arg "Str.group_end";
|
||||
let pos = snd (offset_group n) in
|
||||
if pos = -1 then
|
||||
raise Not_found
|
||||
else
|
||||
pos
|
||||
|
||||
let matched_group n txt =
|
||||
let (b, e) = offset_group n in
|
||||
String.sub txt b (e - b)
|
||||
|
||||
let replace_matched repl matched = replacement_text repl matched
|
||||
|
||||
let match_beginning () = group_beginning 0
|
||||
and match_end () = group_end 0
|
||||
and matched_string txt = matched_group 0 txt
|
||||
|
||||
let substitute_first expr repl_fun text =
|
||||
try
|
||||
let pos = search_forward expr text 0 in
|
||||
String.concat "" [string_before text pos;
|
||||
repl_fun text;
|
||||
string_after text (match_end ())]
|
||||
with Not_found ->
|
||||
text
|
||||
|
||||
let global_substitute expr repl_fun text =
|
||||
let rec replace accu start last_was_empty =
|
||||
let startpos = if last_was_empty then start + 1 else start in
|
||||
if startpos > String.length text then
|
||||
(string_after text start) :: accu
|
||||
else
|
||||
match search_forward expr text startpos with
|
||||
| pos ->
|
||||
let end_pos = match_end () in
|
||||
let repl_text = repl_fun text in
|
||||
replace (repl_text :: String.sub text start (pos-start) :: accu)
|
||||
end_pos (end_pos = pos)
|
||||
| exception Not_found -> (string_after text start) :: accu
|
||||
in
|
||||
String.concat "" (List.rev (replace [] 0 false))
|
||||
|
||||
let global_replace expr repl text =
|
||||
global_substitute expr (replacement_text repl) text
|
||||
and replace_first expr repl text =
|
||||
substitute_first expr (replacement_text repl) text
|
||||
|
||||
let search_forward_progress re s p =
|
||||
let pos = search_forward re s p in
|
||||
if match_end () > p then
|
||||
pos
|
||||
else if p < String.length s then
|
||||
search_forward re s (p + 1)
|
||||
else
|
||||
raise Not_found
|
||||
|
||||
let bounded_split expr text num =
|
||||
let start =
|
||||
if string_match expr text 0 then match_end () else 0 in
|
||||
let rec split accu start n =
|
||||
if start >= String.length text then
|
||||
accu
|
||||
else if n = 1 then
|
||||
(string_after text start) :: accu
|
||||
else
|
||||
try
|
||||
let pos = search_forward_progress expr text start in
|
||||
split ((String.sub text start (pos-start)) :: accu)
|
||||
(match_end ()) (n - 1)
|
||||
with Not_found ->
|
||||
(string_after text start) :: accu in
|
||||
List.rev (split [] start num)
|
||||
|
||||
let split expr text = bounded_split expr text 0
|
||||
|
||||
let bounded_split_delim expr text num =
|
||||
let rec split accu start n =
|
||||
if start > String.length text then
|
||||
accu
|
||||
else if n = 1 then
|
||||
(string_after text start) :: accu
|
||||
else
|
||||
try
|
||||
let pos = search_forward_progress expr text start in
|
||||
split (String.sub text start (pos-start) :: accu)
|
||||
(match_end ()) (n - 1)
|
||||
with Not_found ->
|
||||
(string_after text start) :: accu in
|
||||
if text = "" then
|
||||
[]
|
||||
else
|
||||
List.rev (split [] 0 num)
|
||||
|
||||
let split_delim expr text = bounded_split_delim expr text 0
|
||||
|
||||
type split_result = Text of string | Delim of string
|
||||
|
||||
let bounded_full_split expr text num =
|
||||
let rec split accu start n =
|
||||
if start >= String.length text then
|
||||
accu
|
||||
else if n = 1 then
|
||||
Text (string_after text start) :: accu
|
||||
else
|
||||
try
|
||||
let pos = search_forward_progress expr text start in
|
||||
let s = matched_string text in
|
||||
if pos > start then
|
||||
split (Delim (s) ::
|
||||
Text (String.sub text start (pos - start)) ::
|
||||
accu)
|
||||
(match_end ()) (n - 1)
|
||||
else
|
||||
split (Delim (s) :: accu)
|
||||
(match_end ()) (n - 1)
|
||||
with Not_found ->
|
||||
Text (string_after text start) :: accu in
|
||||
List.rev (split [] 0 num)
|
||||
|
||||
let full_split expr text = bounded_full_split expr text 0
|
||||
218
unikernel/duniverse/dune_/vendor/re/src/str.mli
vendored
Normal file
218
unikernel/duniverse/dune_/vendor/re/src/str.mli
vendored
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
(***********************************************************************)
|
||||
(* *)
|
||||
(* Objective Caml *)
|
||||
(* *)
|
||||
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
||||
(* *)
|
||||
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
||||
(* en Automatique. All rights reserved. This file is distributed *)
|
||||
(* under the terms of the GNU Library General Public License, with *)
|
||||
(* linking exception. *)
|
||||
(* *)
|
||||
(***********************************************************************)
|
||||
|
||||
(* $Id: re_str.mli,v 1.1 2002/01/16 14:16:04 vouillon Exp $ *)
|
||||
|
||||
(** Module [Str]: regular expressions and high-level string processing *)
|
||||
|
||||
(** {2 Regular expressions} *)
|
||||
|
||||
type regexp
|
||||
(** The type of compiled regular expressions. *)
|
||||
|
||||
val regexp: string -> regexp
|
||||
(** Compile a regular expression. The syntax for regular expressions
|
||||
is the same as in Gnu Emacs. The special characters are
|
||||
[$^.*+?[]]. The following constructs are recognized:
|
||||
- [. ] matches any character except newline
|
||||
- [* ] (postfix) matches the previous expression zero, one or
|
||||
several times
|
||||
- [+ ] (postfix) matches the previous expression one or
|
||||
several times
|
||||
- [? ] (postfix) matches the previous expression once or
|
||||
not at all
|
||||
- [[..] ] character set; ranges are denoted with [-], as in [[a-z]];
|
||||
an initial [^], as in [[^0-9]], complements the set
|
||||
- [^ ] matches at beginning of line
|
||||
- [$ ] matches at end of line
|
||||
- [\| ] (infix) alternative between two expressions
|
||||
- [\(..\)] grouping and naming of the enclosed expression
|
||||
- [\1 ] the text matched by the first [\(...\)] expression
|
||||
([\2] for the second expression, etc)
|
||||
- [\b ] matches word boundaries
|
||||
- [\ ] quotes special characters. *)
|
||||
|
||||
val regexp_case_fold: string -> regexp
|
||||
(** Same as [regexp], but the compiled expression will match text
|
||||
in a case-insensitive way: uppercase and lowercase letters will
|
||||
be considered equivalent. *)
|
||||
|
||||
val quote: string -> string
|
||||
(** [Str.quote s] returns a regexp string that matches exactly
|
||||
[s] and nothing else. *)
|
||||
|
||||
val regexp_string: string -> regexp
|
||||
(** [Str.regexp_string s] returns a regular expression
|
||||
that matches exactly [s] and nothing else. *)
|
||||
|
||||
val regexp_string_case_fold: string -> regexp
|
||||
(** [Str.regexp_string_case_fold] is similar to [Str.regexp_string], but the regexp
|
||||
matches in a case-insensitive way. *)
|
||||
|
||||
(** {2 String matching and searching} *)
|
||||
|
||||
val string_match: regexp -> string -> int -> bool
|
||||
(** [string_match r s start] tests whether the characters in [s]
|
||||
starting at position [start] match the regular expression [r].
|
||||
The first character of a string has position [0], as usual. *)
|
||||
|
||||
val search_forward: regexp -> string -> int -> int
|
||||
(** [search_forward r s start] searches the string [s] for a substring
|
||||
matching the regular expression [r]. The search starts at position
|
||||
[start] and proceeds towards the end of the string.
|
||||
Return the position of the first character of the matched
|
||||
substring, or raise [Not_found] if no substring matches. *)
|
||||
|
||||
val search_backward: regexp -> string -> int -> int
|
||||
(** Same as [search_forward], but the search proceeds towards the
|
||||
beginning of the string. *)
|
||||
|
||||
val string_partial_match: regexp -> string -> int -> bool
|
||||
(** Similar to [string_match], but succeeds whenever the argument
|
||||
string is a prefix of a string that matches. This includes
|
||||
the case of a true complete match. *)
|
||||
|
||||
val matched_string: string -> string
|
||||
(** [matched_string s] returns the substring of [s] that was matched
|
||||
by the latest [string_match], [search_forward] or [search_backward].
|
||||
The user must make sure that the parameter [s] is the same string
|
||||
that was passed to the matching or searching function. *)
|
||||
|
||||
val match_beginning: unit -> int
|
||||
(** [match_beginning ()] returns the position of the first character
|
||||
of the substring that was matched by [string_match],
|
||||
[search_forward] or [search_backward]. *)
|
||||
|
||||
val match_end: unit -> int
|
||||
(** [match_end ()] returns the position of the character following the
|
||||
last character of the substring that was matched by [string_match],
|
||||
[search_forward] or [search_backward]. *)
|
||||
|
||||
val matched_group: int -> string -> string
|
||||
(** [matched_group n s] returns the substring of [s] that was matched
|
||||
by the [n]th group [\(...\)] of the regular expression during
|
||||
the latest [string_match], [search_forward] or [search_backward].
|
||||
The user must make sure that the parameter [s] is the same string
|
||||
that was passed to the matching or searching function.
|
||||
[matched_group n s] raises [Not_found] if the [n]th group
|
||||
of the regular expression was not matched. This can happen
|
||||
with groups inside alternatives [\|], options [?]
|
||||
or repetitions [*]. For instance, the empty string will match
|
||||
[\(a\)*], but [matched_group 1 ""] will raise [Not_found]
|
||||
because the first group itself was not matched. *)
|
||||
|
||||
val group_beginning: int -> int
|
||||
(** [group_beginning n] returns the position of the first character
|
||||
of the substring that was matched by the [n]th group of the regular expression.
|
||||
Raises [Not_found] if the [n]th group of the regular expression was not matched. *)
|
||||
|
||||
val group_end: int -> int
|
||||
(** [group_end n] returns the position of the character following
|
||||
the last character of the matched substring.
|
||||
Raises [Not_found] if the [n]th group of the regular expression was not matched. *)
|
||||
|
||||
(** {2 Replacement} *)
|
||||
|
||||
val global_replace: regexp -> string -> string -> string
|
||||
(** [global_replace regexp templ s] returns a string identical to [s],
|
||||
except that all substrings of [s] that match [regexp] have been
|
||||
replaced by [templ]. The replacement template [templ] can contain
|
||||
[\1], [\2], etc; these sequences will be replaced by the text
|
||||
matched by the corresponding group in the regular expression.
|
||||
[\0] stands for the text matched by the whole regular expression. *)
|
||||
|
||||
val replace_first: regexp -> string -> string -> string
|
||||
(** Same as [global_replace], except that only the first substring
|
||||
matching the regular expression is replaced. *)
|
||||
|
||||
val global_substitute: regexp -> (string -> string) -> string -> string
|
||||
(** [global_substitute regexp subst s] returns a string identical
|
||||
to [s], except that all substrings of [s] that match [regexp]
|
||||
have been replaced by the result of function [subst]. The
|
||||
function [subst] is called once for each matching substring,
|
||||
and receives [s] (the whole text) as argument. *)
|
||||
|
||||
val substitute_first: regexp -> (string -> string) -> string -> string
|
||||
(** Same as [global_substitute], except that only the first substring
|
||||
matching the regular expression is replaced. *)
|
||||
|
||||
val replace_matched : string -> string -> string
|
||||
(** [replace_matched repl s] returns the replacement text [repl]
|
||||
in which [\1], [\2], etc. have been replaced by the text
|
||||
matched by the corresponding groups in the most recent matching
|
||||
operation. [s] must be the same string that was matched during
|
||||
this matching operation. *)
|
||||
|
||||
(** {2 Splitting} *)
|
||||
|
||||
val split: regexp -> string -> string list
|
||||
(** [split r s] splits [s] into substrings, taking as delimiters
|
||||
the substrings that match [r], and returns the list of substrings.
|
||||
For instance, [split (regexp "[ \t]+") s] splits [s] into
|
||||
blank-separated words. An occurrence of the delimiter at the
|
||||
beginning and at the end of the string is ignored. *)
|
||||
|
||||
val bounded_split: regexp -> string -> int -> string list
|
||||
(** Same as [split], but splits into at most [n] substrings,
|
||||
where [n] is the extra integer parameter. *)
|
||||
|
||||
val split_delim: regexp -> string -> string list
|
||||
(** Same as [split], but occurrences of the delimiter at the beginning
|
||||
and at the end of the string are recognized and returned as empty strings
|
||||
in the result.
|
||||
For instance, [split_delim (regexp " ") " abc "] returns [[""; "abc"; ""]],
|
||||
while [split] with the same arguments returns [["abc"]]. *)
|
||||
|
||||
val bounded_split_delim: regexp -> string -> int -> string list
|
||||
(** Same as [bounded_split] and [split_delim], but occurrences of
|
||||
the delimiter at the beginning and at the end of the string are recognized
|
||||
and returned as empty strings in the result.
|
||||
For instance, [split_delim (regexp " ") " abc "] returns [[""; "abc"; ""]],
|
||||
while [split] with the same arguments returns [["abc"]]. *)
|
||||
|
||||
type split_result = Text of string | Delim of string
|
||||
|
||||
val full_split: regexp -> string -> split_result list
|
||||
(** Same as [split_delim], but returns the delimiters
|
||||
as well as the substrings contained between delimiters.
|
||||
The former are tagged [Delim] in the result list;
|
||||
the latter are tagged [Text].
|
||||
For instance, [full_split (regexp "[{}]") "{ab}"] returns
|
||||
[[Delim "{"; Text "ab"; Delim "}"]]. *)
|
||||
|
||||
val bounded_full_split: regexp -> string -> int -> split_result list
|
||||
(** Same as [split_delim] and [bounded_split_delim], but returns
|
||||
the delimiters as well as the substrings contained between delimiters.
|
||||
The former are tagged [Delim] in the result list;
|
||||
the latter are tagged [Text].
|
||||
For instance, [full_split (regexp "[{}]") "{ab}"] returns
|
||||
[[Delim "{"; Text "ab"; Delim "}"]]. *)
|
||||
|
||||
(** {2 Extracting substrings} *)
|
||||
|
||||
val string_before: string -> int -> string
|
||||
(** [string_before s n] returns the substring of all characters of [s]
|
||||
that precede position [n] (excluding the character at
|
||||
position [n]). *)
|
||||
|
||||
val string_after: string -> int -> string
|
||||
(** [string_after s n] returns the substring of all characters of [s]
|
||||
that follow position [n] (including the character at
|
||||
position [n]). *)
|
||||
|
||||
val first_chars: string -> int -> string
|
||||
(** [first_chars s n] returns the first [n] characters of [s].
|
||||
This is the same function as [string_before]. *)
|
||||
|
||||
val last_chars: string -> int -> string
|
||||
(** [last_chars s n] returns the last [n] characters of [s]. *)
|
||||
Loading…
Add table
Add a link
Reference in a new issue