+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, 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
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If 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 convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU 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
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state 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 program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+++ /dev/null
-## Process this file with automake to produce Makefile.in
-LIBFFI = @LIBFFI@
-LIBFFIINCS = @LIBFFIINCS@
-
-lib_LTLIBRARIES = libgrust.la
-
-AM_CPPFLAGS = -I$(top_srcdir)/include
-AM_CFLAGS = -g -O2 -std=gnu99 -Wall -Werror -fgcse $(LIBFFIINCS) $(PTHREAD_CFLAGS)
-
-library_includedir = $(includedir)/grust
-library_include_HEADERS = \
- include/rust/rust.h \
- include/rust/lang-hooks.h
-
-libgrust_la_CFLAGS = -DGRUST -DSHARED -g -O2 -std=gnu99 -Wall -Werror $(LIBFFIINCS) $(PTHREAD_CFLAGS)
-libgrust_la_LDFLAGS = -release 0.1.0 $(LIBFFI) $(PTHREAD_CFLAGS) $(AM_LDFLAGS)
-libgrust_la_LIBADD = $(PTHREAD_LIBS) $(MATH_LIBS)
-libgrust_la_SOURCES = \
- src/rust-main.c \
- src/lang-hooks.c
+++ /dev/null
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-target_triplet = @target@
-subdir = .
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
- $(srcdir)/../depcomp $(library_include_HEADERS)
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
- configure.lineno config.status.lineno
-mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
-CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(libdir)" \
- "$(DESTDIR)$(library_includedir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libgrust_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am_libgrust_la_OBJECTS = libgrust_la-rust-main.lo \
- libgrust_la-lang-hooks.lo
-libgrust_la_OBJECTS = $(am_libgrust_la_OBJECTS)
-libgrust_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgrust_la_CFLAGS) \
- $(CFLAGS) $(libgrust_la_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I.@am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/../depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libgrust_la_SOURCES)
-HEADERS = $(library_include_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CC_FOR_BUILD = @CC_FOR_BUILD@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBFFI = @LIBFFI@
-LIBFFIINCS = @LIBFFIINCS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MATH_LIBS = @MATH_LIBS@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJCOPY = @OBJCOPY@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-WARN_FLAGS = @WARN_FLAGS@
-WERROR = @WERROR@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-enable_shared = @enable_shared@
-enable_static = @enable_static@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-libtool_VERSION = @libtool_VERSION@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target = @target@
-target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-lib_LTLIBRARIES = libgrust.la
-AM_CPPFLAGS = -I$(top_srcdir)/include
-AM_CFLAGS = -g -O2 -std=gnu99 -Wall -Werror -fgcse $(LIBFFIINCS) $(PTHREAD_CFLAGS)
-library_includedir = $(includedir)/grust
-library_include_HEADERS = \
- include/rust/rust.h \
- include/rust/lang-hooks.h
-
-libgrust_la_CFLAGS = -DGRUST -DSHARED -g -O2 -std=gnu99 -Wall -Werror $(LIBFFIINCS) $(PTHREAD_CFLAGS)
-libgrust_la_LDFLAGS = -release 0.1.0 $(LIBFFI) $(PTHREAD_CFLAGS) $(AM_LDFLAGS)
-libgrust_la_LIBADD = $(PTHREAD_LIBS) $(MATH_LIBS)
-libgrust_la_SOURCES = \
- src/rust-main.c \
- src/lang-hooks.c
-
-all: config.h
- $(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-am--refresh:
- @:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
- $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- echo ' $(SHELL) ./config.status'; \
- $(SHELL) ./config.status;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- $(SHELL) ./config.status --recheck
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- $(am__cd) $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
-$(am__aclocal_m4_deps):
-
-config.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
- else :; fi
-
-stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
- @rm -f stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
- rm -f stamp-h1
- touch $@
-
-distclean-hdr:
- -rm -f config.h stamp-h1
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
- list2=; for p in $$list; do \
- if test -f $$p; then \
- list2="$$list2 $$p"; \
- else :; fi; \
- done; \
- test -z "$$list2" || { \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
- }
-
-uninstall-libLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
- for p in $$list; do \
- $(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
- done
-
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libgrust.la: $(libgrust_la_OBJECTS) $(libgrust_la_DEPENDENCIES)
- $(libgrust_la_LINK) -rpath $(libdir) $(libgrust_la_OBJECTS) $(libgrust_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrust_la-lang-hooks.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrust_la-rust-main.Plo@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-libgrust_la-rust-main.lo: src/rust-main.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrust_la_CFLAGS) $(CFLAGS) -MT libgrust_la-rust-main.lo -MD -MP -MF $(DEPDIR)/libgrust_la-rust-main.Tpo -c -o libgrust_la-rust-main.lo `test -f 'src/rust-main.c' || echo '$(srcdir)/'`src/rust-main.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgrust_la-rust-main.Tpo $(DEPDIR)/libgrust_la-rust-main.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rust-main.c' object='libgrust_la-rust-main.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrust_la_CFLAGS) $(CFLAGS) -c -o libgrust_la-rust-main.lo `test -f 'src/rust-main.c' || echo '$(srcdir)/'`src/rust-main.c
-
-libgrust_la-lang-hooks.lo: src/lang-hooks.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrust_la_CFLAGS) $(CFLAGS) -MT libgrust_la-lang-hooks.lo -MD -MP -MF $(DEPDIR)/libgrust_la-lang-hooks.Tpo -c -o libgrust_la-lang-hooks.lo `test -f 'src/lang-hooks.c' || echo '$(srcdir)/'`src/lang-hooks.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgrust_la-lang-hooks.Tpo $(DEPDIR)/libgrust_la-lang-hooks.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/lang-hooks.c' object='libgrust_la-lang-hooks.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrust_la_CFLAGS) $(CFLAGS) -c -o libgrust_la-lang-hooks.lo `test -f 'src/lang-hooks.c' || echo '$(srcdir)/'`src/lang-hooks.c
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-distclean-libtool:
- -rm -f libtool config.lt
-install-library_includeHEADERS: $(library_include_HEADERS)
- @$(NORMAL_INSTALL)
- test -z "$(library_includedir)" || $(MKDIR_P) "$(DESTDIR)$(library_includedir)"
- @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; \
- done | $(am__base_list) | \
- while read files; do \
- echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(library_includedir)'"; \
- $(INSTALL_HEADER) $$files "$(DESTDIR)$(library_includedir)" || exit $$?; \
- done
-
-uninstall-library_includeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \
- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- test -n "$$files" || exit 0; \
- echo " ( cd '$(DESTDIR)$(library_includedir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(library_includedir)" && rm -f $$files
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- set x; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
-installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-hdr distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-library_includeHEADERS
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-libLTLIBRARIES
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-libLTLIBRARIES \
- uninstall-library_includeHEADERS
-
-.MAKE: all install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
- clean-generic clean-libLTLIBRARIES clean-libtool ctags \
- distclean distclean-compile distclean-generic distclean-hdr \
- distclean-libtool distclean-tags dvi dvi-am html html-am info \
- info-am install install-am install-data install-data-am \
- install-dvi install-dvi-am install-exec install-exec-am \
- install-html install-html-am install-info install-info-am \
- install-libLTLIBRARIES install-library_includeHEADERS \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
- uninstall-am uninstall-libLTLIBRARIES \
- uninstall-library_includeHEADERS
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
+++ /dev/null
-* librust
-TODO
+++ /dev/null
-TO notes:
-
-This is the Rust runtime library, i.e. not the actual compiler bit.
\ No newline at end of file
+++ /dev/null
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
-[m4_warning([this file was generated for autoconf 2.64.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
-
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 9
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-m4_define([_AM_COND_VALUE_$1], [$2])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 10
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- am__universal=false
- m4_case([$1], [CC],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac],
- [CXX],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac])
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-#serial 5
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 16
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
-])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
-AC_CONFIG_COMMANDS_PRE(dnl
-[m4_provide_if([_AM_COMPILER_EXEEXT],
- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
-dnl mangled by Autoconf and run in a shell conditional statement.
-m4_define([_AC_COMPILER_EXEEXT],
-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-AC_SUBST(install_sh)])
-
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
-# From Jim Meyering
-
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_MAINTAINER_MODE([DEFAULT-MODE])
-# ----------------------------------
-# Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless `enable' is passed literally.
-# For symmetry, `disable' may be passed as well. Anyway, the user
-# can override the default with the --enable/--disable switch.
-AC_DEFUN([AM_MAINTAINER_MODE],
-[m4_case(m4_default([$1], [disable]),
- [enable], [m4_define([am_maintainer_other], [disable])],
- [disable], [m4_define([am_maintainer_other], [enable])],
- [m4_define([am_maintainer_other], [enable])
- m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
- dnl maintainer-mode's default is 'disable' unless 'enable' is passed
- AC_ARG_ENABLE([maintainer-mode],
-[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- [USE_MAINTAINER_MODE=$enableval],
- [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
- AC_MSG_RESULT([$USE_MAINTAINER_MODE])
- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST([MAINT])dnl
-]
-)
-
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 6
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[[\\\"\#\$\&\'\`$am_lf]]*)
- AC_MSG_ERROR([unsafe absolute working directory name]);;
-esac
-case $srcdir in
- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Public sister of _AM_SUBST_NOTMAKE.
-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
-m4_include([../libtool.m4])
-m4_include([../ltoptions.m4])
-m4_include([../ltsugar.m4])
-m4_include([../ltversion.m4])
-m4_include([../lt~obsolete.m4])
+++ /dev/null
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
-/* Define to 1 if you have the `atof' function. */
-#undef HAVE_ATOF
-
-/* Define to 1 if you have the `atoi' function. */
-#undef HAVE_ATOI
-
-/* Define to 1 if you have the `calloc' function. */
-#undef HAVE_CALLOC
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
-/* Define to 1 if you have the `execl' function. */
-#undef HAVE_EXECL
-
-/* Define to 1 if you have the `exit' function. */
-#undef HAVE_EXIT
-
-/* Define to 1 if you have the `fclose' function. */
-#undef HAVE_FCLOSE
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `fdopen' function. */
-#undef HAVE_FDOPEN
-
-/* Define to 1 if you have the `fgets' function. */
-#undef HAVE_FGETS
-
-/* Define to 1 if you have the `fopen' function. */
-#undef HAVE_FOPEN
-
-/* Define to 1 if you have the `fork' function. */
-#undef HAVE_FORK
-
-/* Define to 1 if you have the `fprintf' function. */
-#undef HAVE_FPRINTF
-
-/* Define to 1 if you have the `getc' function. */
-#undef HAVE_GETC
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#undef HAVE_GETOPT_H
-
-/* Define to 1 if you have the `getopt_long' function. */
-#undef HAVE_GETOPT_LONG
-
-/* Define to 1 if you have the `getpid' function. */
-#undef HAVE_GETPID
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#undef HAVE_MALLOC
-
-/* Define to 1 if you have the `memcmp' function. */
-#undef HAVE_MEMCMP
-
-/* Define to 1 if you have the `memcpy' function. */
-#undef HAVE_MEMCPY
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `pipe' function. */
-#undef HAVE_PIPE
-
-/* Define to 1 if you have the `popen' function. */
-#undef HAVE_POPEN
-
-/* Define to 1 if you have the <pthread.h> header file. */
-#undef HAVE_PTHREAD_H
-
-/* Define to 1 if you have the <signal.h> header file. */
-#undef HAVE_SIGNAL_H
-
-/* Define to 1 if you have the `sprintf' function. */
-#undef HAVE_SPRINTF
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#undef HAVE_STDARG_H
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#undef HAVE_STDBOOL_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#undef HAVE_STDIO_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcmp' function. */
-#undef HAVE_STRCMP
-
-/* Define to 1 if you have the `strcpy' function. */
-#undef HAVE_STRCPY
-
-/* Define to 1 if you have the `strdup' function. */
-#undef HAVE_STRDUP
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strlen' function. */
-#undef HAVE_STRLEN
-
-/* Define to 1 if you have the `sysconf' function. */
-#undef HAVE_SYSCONF
-
-/* Define to 1 if you have the `system' function. */
-#undef HAVE_SYSTEM
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the <utime.h> header file. */
-#undef HAVE_UTIME_H
-
-/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
-#undef HAVE_UTIME_NULL
-
-/* Define to 1 if you have the `vfprintf' function. */
-#undef HAVE_VFPRINTF
-
-/* Define to 1 if you have the `vprintf' function. */
-#undef HAVE_VPRINTF
-
-/* Define to 1 if you have the `wait' function. */
-#undef HAVE_WAIT
-
-/* Define to 1 if you have the `waitpid' function. */
-#undef HAVE_WAITPID
-
-/* Define to 1 if the system has the type `_Bool'. */
-#undef HAVE__BOOL
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
-/* GCC Rust Runtime */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define if we're to use libffi. */
-#undef USE_LIBFFI
-
-/* 0.1 */
-#undef VERSION
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-# undef WORDS_BIGENDIAN
-# endif
-#endif
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to rpl_malloc if the replacement function should be used. */
-#undef malloc
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
+++ /dev/null
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for GCC-Rust-runtime 0.1.
-#
-# Report bugs to <http://gcc.gnu.org>.
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-# Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '\${1+\"\$@\"}'='\"\$@\"'
- setopt NO_GLOB_SUBST
-else
- case \`(set -o) 2>/dev/null\` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-"
- as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
- exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1"
- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1
-
- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
- PATH=/empty FPATH=/empty; export PATH FPATH
- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
- if (eval "$as_required") 2>/dev/null; then :
- as_have_required=yes
-else
- as_have_required=no
-fi
- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- as_found=:
- case $as_dir in #(
- /*)
- for as_base in sh bash ksh sh5; do
- # Try only shells that exist, to save several forks.
- as_shell=$as_dir/$as_base
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
- CONFIG_SHELL=$as_shell as_have_required=yes
- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
- break 2
-fi
-fi
- done;;
- esac
- as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
- CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
- if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
- if test x$as_have_required = xno; then :
- $as_echo "$0: This script requires a shell more modern than all"
- $as_echo "$0: the shells that I found on your system."
- if test x${ZSH_VERSION+set} = xset ; then
- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
- $as_echo "$0: be upgraded to zsh 4.3.4 or later."
- else
- $as_echo "$0: Please tell bug-autoconf@gnu.org and http://gcc.gnu.org
-$0: about your system, including any error possibly output
-$0: before this message. Then install a modern shell, or
-$0: manually run the script under such a shell if you do
-$0: have one."
- fi
- exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
- fi
- $as_echo "$as_me: error: $1" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME='GCC-Rust-runtime'
-PACKAGE_TARNAME='libgrust'
-PACKAGE_VERSION='0.1'
-PACKAGE_STRING='GCC-Rust-runtime 0.1'
-PACKAGE_BUGREPORT='http://gcc.gnu.org'
-PACKAGE_URL='https://github.com/redbrain/gccrs'
-
-ac_unique_file="Makefile.am"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_header_list=
-ac_subst_vars='am__EXEEXT_FALSE
-am__EXEEXT_TRUE
-LTLIBOBJS
-LIBOBJS
-PTHREAD_LIBS
-PTHREAD_CFLAGS
-MATH_LIBS
-LIBFFIINCS
-LIBFFI
-WERROR
-WARN_FLAGS
-CC_FOR_BUILD
-enable_static
-enable_shared
-CPP
-OTOOL64
-OTOOL
-LIPO
-NMEDIT
-DSYMUTIL
-RANLIB
-AR
-OBJDUMP
-LN_S
-NM
-ac_ct_DUMPBIN
-DUMPBIN
-LIBTOOL
-OBJCOPY
-LD
-FGREP
-EGREP
-GREP
-SED
-MAINT
-MAINTAINER_MODE_FALSE
-MAINTAINER_MODE_TRUE
-am__fastdepCC_FALSE
-am__fastdepCC_TRUE
-CCDEPMODE
-AMDEPBACKSLASH
-AMDEP_FALSE
-AMDEP_TRUE
-am__quote
-am__include
-DEPDIR
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-am__untar
-am__tar
-AMTAR
-am__leading_dot
-SET_MAKE
-AWK
-mkdir_p
-MKDIR_P
-INSTALL_STRIP_PROGRAM
-STRIP
-install_sh
-MAKEINFO
-AUTOHEADER
-AUTOMAKE
-AUTOCONF
-ACLOCAL
-VERSION
-PACKAGE
-CYGPATH_W
-am__isrc
-INSTALL_DATA
-INSTALL_SCRIPT
-INSTALL_PROGRAM
-target_os
-target_vendor
-target_cpu
-target
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
-libtool_VERSION
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-enable_dependency_tracking
-enable_maintainer_mode
-with_gnu_ld
-enable_shared
-enable_static
-with_pic
-enable_fast_install
-enable_libtool_lock
-with_libffi
-'
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CPP
-CPPFLAGS'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- case $ac_envvar in #(
- '' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error "invalid variable name: \`$ac_envvar'" ;;
- esac
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
- case $enable_option_checking in
- no) ;;
- fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
- esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- # Remove trailing slashes.
- case $ac_val in
- */ )
- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
- eval $ac_var=\$ac_val;;
- esac
- # Be sure to have absolute directory names.
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_myself" : 'X\(//\)[^/]' \| \
- X"$as_myself" : 'X\(//\)$' \| \
- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures GCC-Rust-runtime 0.1 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/libgrust]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-Program names:
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM run sed PROGRAM on installed program names
-
-System types:
- --build=BUILD configure for building on BUILD [guessed]
- --host=HOST cross-compile to build programs to run on HOST [BUILD]
- --target=TARGET configure for building compilers for TARGET [HOST]
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
- case $ac_init_help in
- short | recursive ) echo "Configuration of GCC-Rust-runtime 0.1:";;
- esac
- cat <<\_ACEOF
-
-Optional Features:
- --disable-option-checking ignore unrecognized --enable/--with options
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
- --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer
- --enable-shared[=PKGS] build shared libraries [default=yes]
- --enable-static[=PKGS] build static libraries [default=yes]
- --enable-fast-install[=PKGS]
- optimize for fast installation [default=yes]
- --disable-libtool-lock avoid locking (might break parallel builds)
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-gnu-ld assume the C compiler uses GNU ld [default=no]
- --with-pic try to use only PIC/non-PIC objects [default=use
- both]
- --without-libffi don't use libffi
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CPP C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <http://gcc.gnu.org>.
-GCC-Rust-runtime home page: <https://github.com/redbrain/gccrs>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" ||
- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
- continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-GCC-Rust-runtime configure 0.1
-generated by GNU Autoconf 2.64
-
-Copyright (C) 2009 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then :
- ac_retval=0
-else
- $as_echo "$as_me: program exited with status $ac_status" >&5
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=$ac_status
-fi
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_func
-
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof ($2))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_type
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
- # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_header_compiler=yes
-else
- ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- ac_header_preproc=yes
-else
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
- yes:no: )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
- no:yes:* )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( cat <<\_ASBOX
-## --------------------------------- ##
-## Report this to http://gcc.gnu.org ##
-## --------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_mongrel
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by GCC-Rust-runtime $as_me 0.1, which was
-generated by GNU Autoconf 2.64. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- $as_echo "PATH: $as_dir"
- done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
- 2)
- as_fn_append ac_configure_args1 " '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- as_fn_append ac_configure_args " '$ac_arg'"
- ;;
- esac
- done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- $as_echo "$as_me: caught signal $ac_signal"
- $as_echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
- ac_site_file1=$CONFIG_SITE
-elif test "x$prefix" != xNONE; then
- ac_site_file1=$prefix/share/config.site
- ac_site_file2=$prefix/etc/config.site
-else
- ac_site_file1=$ac_default_prefix/share/config.site
- ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
- test "x$ac_site_file" = xNONE && continue
- if test -r "$ac_site_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-as_fn_append ac_header_list " utime.h"
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- # differences in whitespace do not lead to failure.
- ac_old_val_w=`echo x $ac_old_val`
- ac_new_val_w=`echo x $ac_new_val`
- if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- ac_cache_corrupted=:
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
- eval $ac_var=\$ac_old_val
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) as_fn_append ac_configure_args " '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-ac_config_headers="$ac_config_headers config.h"
-
-
-libtool_VERSION=1:0:0
-
-
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- for ac_t in install-sh install.sh shtool; do
- if test -f "$ac_dir/$ac_t"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/$ac_t -c"
- break 2
- fi
- done
-done
-if test -z "$ac_aux_dir"; then
- as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
-$as_echo_n "checking target system type... " >&6; }
-if test "${ac_cv_target+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$target_alias" = x; then
- ac_cv_target=$ac_cv_host
-else
- ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
-$as_echo "$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-target_alias=${target_alias-$host_alias}
-
-
-am__api_version='1.11'
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-# Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
- ./ | .// | /[cC]/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- rm -rf conftest.one conftest.two conftest.dir
- echo one > conftest.one
- echo two > conftest.two
- mkdir conftest.dir
- if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
- test -s conftest.one && test -s conftest.two &&
- test -s conftest.dir/conftest.one &&
- test -s conftest.dir/conftest.two
- then
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- fi
- done
- done
- ;;
-esac
-
- done
-IFS=$as_save_IFS
-
-rm -rf conftest.one conftest.two conftest.dir
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
-$as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[\\\"\#\$\&\'\`$am_lf]*)
- as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
-esac
-case $srcdir in
- *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error "ls -t appears to fail. Make sure there is not a broken
-alias in your environment" "$LINENO" 5
- fi
-
- test "$2" = conftest.file
- )
-then
- # Ok.
- :
-else
- as_fn_error "newly created file is older than distributed files!
-Check your system clock" "$LINENO" 5
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-test "$program_prefix" != NONE &&
- program_transform_name="s&^&$program_prefix&;$program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s&\$&$program_suffix&;$program_transform_name"
-# Double any \ or $.
-# By default was `s,x,x', remove it if useless.
-ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
-fi
-
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-if test "$cross_compiling" != no; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_STRIP="strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
-if test -z "$MKDIR_P"; then
- if test "${ac_cv_path_mkdir+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in mkdir gmkdir; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
- case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
- 'mkdir (GNU coreutils) '* | \
- 'mkdir (coreutils) '* | \
- 'mkdir (fileutils) '4.1*)
- ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
- break 3;;
- esac
- done
- done
- done
-IFS=$as_save_IFS
-
-fi
-
- if test "${ac_cv_path_mkdir+set}" = set; then
- MKDIR_P="$ac_cv_path_mkdir -p"
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for MKDIR_P within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- test -d ./--version && rmdir ./--version
- MKDIR_P="$ac_install_sh -d"
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
-$as_echo "$MKDIR_P" >&6; }
-
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
-for ac_prog in gawk mawk nawk awk
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AWK="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
-set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
- *@@@%%%=?*=@@@%%%*)
- eval ac_cv_prog_make_${ac_make}_set=yes;;
- *)
- eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- SET_MAKE=
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- am__isrc=' -I$(srcdir)'
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-
-
-# Define the identity of the package.
- PACKAGE='libgrust'
- VERSION='0.1'
-
-
-# Some tools Automake needs.
-
-ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
-
-
-AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
-
-
-AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
-
-
-AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
-
-
-MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
-
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-# Always define AMTAR for backward compatibility.
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
-
-
-
-
-
-
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- rm -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-if test -z "$ac_file"; then :
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
-fi
-ac_exeext=$ac_cv_exeext
-
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-rm -f conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GCC=yes
-else
- GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-else
- CFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-DEPDIR="${am__leading_dot}deps"
-
-ac_config_commands="$ac_config_commands depfiles"
-
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
-
-# Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
- enableval=$enable_dependency_tracking;
-fi
-
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
- if test "x$enable_dependency_tracking" != xno; then
- AMDEP_TRUE=
- AMDEP_FALSE='#'
-else
- AMDEP_TRUE='#'
- AMDEP_FALSE=
-fi
-
-
-
-depcc="$CC" am_compiler_list=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_CC_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- am__universal=false
- case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CC_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_CC_dependencies_compiler_type=none
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
-
- if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
- am__fastdepCC_TRUE=
- am__fastdepCC_FALSE='#'
-else
- am__fastdepCC_TRUE='#'
- am__fastdepCC_FALSE=
-fi
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
-$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
- # Check whether --enable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then :
- enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
-else
- USE_MAINTAINER_MODE=no
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
-$as_echo "$USE_MAINTAINER_MODE" >&6; }
- if test $USE_MAINTAINER_MODE = yes; then
- MAINTAINER_MODE_TRUE=
- MAINTAINER_MODE_FALSE='#'
-else
- MAINTAINER_MODE_TRUE='#'
- MAINTAINER_MODE_FALSE=
-fi
-
- MAINT=$MAINTAINER_MODE_TRUE
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
-$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for ac_i in 1 2 3 4 5 6 7; do
- ac_script="$ac_script$as_nl$ac_script"
- done
- echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
- { ac_script=; unset ac_script;}
- if test -z "$SED"; then
- ac_path_SED_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
-# Check for GNU ac_path_SED and select it if it is found.
- # Check for GNU $ac_path_SED
-case `"$ac_path_SED" --version 2>&1` in
-*GNU*)
- ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo '' >> "conftest.nl"
- "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_SED_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_SED="$ac_path_SED"
- ac_path_SED_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_SED_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_SED"; then
- as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
- fi
-else
- ac_cv_path_SED=$SED
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
-$as_echo "$ac_cv_path_SED" >&6; }
- SED="$ac_cv_path_SED"
- rm -f conftest.sed
-
-test -z "$SED" && SED=sed
-Xsed="$SED -e 1s/^X//"
-
-
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$GREP"; then
- ac_path_GREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-# Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_GREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_GREP"; then
- as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- if test -z "$EGREP"; then
- ac_path_EGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_EGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_EGREP"; then
- as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
-$as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
- then ac_cv_path_FGREP="$GREP -F"
- else
- if test -z "$FGREP"; then
- ac_path_FGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in fgrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
-# Check for GNU ac_path_FGREP and select it if it is found.
- # Check for GNU $ac_path_FGREP
-case `"$ac_path_FGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'FGREP' >> "conftest.nl"
- "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_FGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_FGREP="$ac_path_FGREP"
- ac_path_FGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_FGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_FGREP"; then
- as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_FGREP=$FGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
-$as_echo "$ac_cv_path_FGREP" >&6; }
- FGREP="$ac_cv_path_FGREP"
-
-
-test -z "$GREP" && GREP=grep
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
-$as_echo_n "checking how to print strings... " >&6; }
-# Test print first, because it will be a builtin if present.
-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
- ECHO='print -r --'
-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
- ECHO='printf %s\n'
-else
- # Use this function as a fallback that always works.
- func_fallback_echo ()
- {
- eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
- }
- ECHO='func_fallback_echo'
-fi
-
-# func_echo_all arg...
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
- $ECHO ""
-}
-
-case "$ECHO" in
- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
-$as_echo "printf" >&6; } ;;
- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
-$as_echo "print -r" >&6; } ;;
- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
-$as_echo "cat" >&6; } ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
-$as_echo_n "checking for ld used by $CC... " >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
- while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
-$as_echo "$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
-set dummy ${ac_tool_prefix}objcopy; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJCOPY+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OBJCOPY"; then
- ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OBJCOPY=$ac_cv_prog_OBJCOPY
-if test -n "$OBJCOPY"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCOPY" >&5
-$as_echo "$OBJCOPY" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OBJCOPY"; then
- ac_ct_OBJCOPY=$OBJCOPY
- # Extract the first word of "objcopy", so it can be a program name with args.
-set dummy objcopy; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OBJCOPY"; then
- ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OBJCOPY="objcopy"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY
-if test -n "$ac_ct_OBJCOPY"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCOPY" >&5
-$as_echo "$ac_ct_OBJCOPY" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OBJCOPY" = x; then
- OBJCOPY="missing-objcopy"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OBJCOPY=$ac_ct_OBJCOPY
- fi
-else
- OBJCOPY="$ac_cv_prog_OBJCOPY"
-fi
-
-
-enable_dlopen=yes
-
-
-
-case `pwd` in
- *\ * | *\ *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
-$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
-esac
-
-
-
-macro_version='2.2.7a'
-macro_revision='1.3134'
-
-
-
-
-
-
-
-
-
-
-
-
-
-ltmain="$ac_aux_dir/ltmain.sh"
-
-# Backslashify metacharacters that are still active within
-# double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
-$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
-if test "${lt_cv_path_NM+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- : ${lt_cv_path_NM=no}
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
-$as_echo "$lt_cv_path_NM" >&6; }
-if test "$lt_cv_path_NM" != "no"; then
- NM="$lt_cv_path_NM"
-else
- # Didn't find any BSD compatible name lister, look for dumpbin.
- if test -n "$DUMPBIN"; then :
- # Let the user override the test.
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in dumpbin "link -dump"
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$DUMPBIN"; then
- ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-DUMPBIN=$ac_cv_prog_DUMPBIN
-if test -n "$DUMPBIN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
-$as_echo "$DUMPBIN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$DUMPBIN" && break
- done
-fi
-if test -z "$DUMPBIN"; then
- ac_ct_DUMPBIN=$DUMPBIN
- for ac_prog in dumpbin "link -dump"
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_DUMPBIN"; then
- ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
-if test -n "$ac_ct_DUMPBIN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
-$as_echo "$ac_ct_DUMPBIN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_DUMPBIN" && break
-done
-
- if test "x$ac_ct_DUMPBIN" = x; then
- DUMPBIN=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- DUMPBIN=$ac_ct_DUMPBIN
- fi
-fi
-
- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
- *COFF*)
- DUMPBIN="$DUMPBIN -symbols"
- ;;
- *)
- DUMPBIN=:
- ;;
- esac
- fi
-
- if test "$DUMPBIN" != ":"; then
- NM="$DUMPBIN"
- fi
-fi
-test -z "$NM" && NM=nm
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
-$as_echo_n "checking the name lister ($NM) interface... " >&6; }
-if test "${lt_cv_nm_interface+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
- (eval echo "\"\$as_me:$LINENO: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
- fi
- rm -f conftest*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
-$as_echo "$lt_cv_nm_interface" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
-$as_echo "no, using $LN_S" >&6; }
-fi
-
-# find the maximum length of command line arguments
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
-$as_echo_n "checking the maximum length of command line arguments... " >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw* | cegcc*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- mint*)
- # On MiNT this can take a long time and run out of memory.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- # Make teststring a little bigger before we do anything with it.
- # a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8 ; do
- teststring=$teststring$teststring
- done
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- # If test is not a shell built-in, we'll probably end up computing a
- # maximum length that is only half of the actual maximum length, but
- # we can't tell.
- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
- = "X$teststring$teststring"; } >/dev/null 2>&1 &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- # Only check the string length outside the loop.
- lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
- teststring=
- # Add a significant safety factor because C++ compilers can tack on
- # massive amounts of additional arguments before passing them to the
- # linker. It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-
-fi
-
-if test -n $lt_cv_sys_max_cmd_len ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
-$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
-$as_echo "none" >&6; }
-fi
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-
-
-
-
-
-: ${CP="cp -f"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
-$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
- && eval 'test $(( 1 + 1 )) -eq 2 \
- && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
- && xsi_shell=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
-$as_echo "$xsi_shell" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
-$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
- >/dev/null 2>&1 \
- && lt_shell_append=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
-$as_echo "$lt_shell_append" >&6; }
-
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- lt_unset=unset
-else
- lt_unset=false
-fi
-
-
-
-
-
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
- # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
- lt_SP2NL='tr \040 \012'
- lt_NL2SP='tr \015\012 \040\040'
- ;;
- *) # EBCDIC based system
- lt_SP2NL='tr \100 \n'
- lt_NL2SP='tr \r\n \100\100'
- ;;
-esac
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
-$as_echo_n "checking for $LD option to reload object files... " >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_reload_flag='-r'
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
-$as_echo "$lt_cv_ld_reload_flag" >&6; }
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
-set dummy ${ac_tool_prefix}objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OBJDUMP"; then
- ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OBJDUMP=$ac_cv_prog_OBJDUMP
-if test -n "$OBJDUMP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
-$as_echo "$OBJDUMP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OBJDUMP"; then
- ac_ct_OBJDUMP=$OBJDUMP
- # Extract the first word of "objdump", so it can be a program name with args.
-set dummy objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OBJDUMP"; then
- ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OBJDUMP="objdump"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
-if test -n "$ac_ct_OBJDUMP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
-$as_echo "$ac_ct_OBJDUMP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OBJDUMP" = x; then
- OBJDUMP="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OBJDUMP=$ac_ct_OBJDUMP
- fi
-else
- OBJDUMP="$ac_cv_prog_OBJDUMP"
-fi
-
-test -z "$OBJDUMP" && OBJDUMP=objdump
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
-$as_echo_n "checking how to recognize dependent libraries... " >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[4-9]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[45]*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-cegcc*)
- # use the weaker test based on 'objdump'. See mingw*.
- lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-haiku*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[3-9]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-*nto* | *qnx*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-tpf*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
-$as_echo "$lt_cv_deplibs_check_method" >&6; }
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AR="${ac_tool_prefix}ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_AR"; then
- ac_ct_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_AR"; then
- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_AR="ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
-$as_echo "$ac_ct_AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_AR" = x; then
- AR="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- AR=$ac_ct_AR
- fi
-else
- AR="$ac_cv_prog_AR"
-fi
-
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_STRIP="strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-test -z "$STRIP" && STRIP=:
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-test -z "$RANLIB" && RANLIB=:
-
-
-
-
-
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-case $host_os in
- darwin*)
- lock_old_archive_extraction=yes ;;
- *)
- lock_old_archive_extraction=no ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
-$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[BCDT]'
- ;;
-cygwin* | mingw* | pw32* | cegcc*)
- symcode='[ABCDGISTW]'
- ;;
-hpux*)
- if test "$host_cpu" = ia64; then
- symcode='[ABCDEGRST]'
- fi
- ;;
-irix* | nonstopux*)
- symcode='[BCDEGRST]'
- ;;
-osf*)
- symcode='[BCDEGQRST]'
- ;;
-solaris*)
- symcode='[BDRT]'
- ;;
-sco3.2v5*)
- symcode='[DT]'
- ;;
-sysv4.2uw2*)
- symcode='[DT]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[ABDT]'
- ;;
-sysv4)
- symcode='[DFNSTU]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[ABCDGIRSTW]' ;;
-esac
-
-# Transform an extracted symbol line into a proper C declaration.
-# Some systems (esp. on ia64) link data and code symbols differently,
-# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# Try without a prefix underscore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function
- # and D for any global variable.
- # Also find C++ and __fastcall symbols from MSVC++,
- # which start with @ or ?.
- lt_cv_sys_global_symbol_pipe="$AWK '"\
-" {last_section=section; section=\$ 3};"\
-" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" \$ 0!~/External *\|/{next};"\
-" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
-" {if(hide[section]) next};"\
-" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
-" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
-" s[1]~/^[@?]/{print s[1], s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
-" ' prfx=^$ac_symprfx"
- else
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
- fi
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<_LT_EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(void);
-void nm_test_func(void){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-_LT_EOF
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
- if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<_LT_EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_LT_EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
-
- cat <<_LT_EOF >> conftest.$ac_ext
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- void *address;
-}
-lt__PROGRAM__LTX_preloaded_symbols[] =
-{
- { "@PROGRAM@", (void *) 0 },
-_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
- cat <<\_LT_EOF >> conftest.$ac_ext
- {0, (void *) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt__PROGRAM__LTX_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-_LT_EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&5
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&5
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
- fi
- else
- echo "$progname: failed program was:" >&5
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-
-fi
-
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then :
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '#line '$LINENO' "configure"' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- case `/usr/bin/file conftest.o` in
- *x86-64*)
- LD="${LD-ld} -m elf32_x86_64"
- ;;
- *)
- LD="${LD-ld} -m elf_i386"
- ;;
- esac
- ;;
- powerpc64le-*linux*)
- LD="${LD-ld} -m elf32lppclinux"
- ;;
- powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- powerpcle-*linux*)
- LD="${LD-ld} -m elf64lppc"
- ;;
- powerpc-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*|s390*-*tpf*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
-$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- lt_cv_cc_needs_belf=yes
-else
- lt_cv_cc_needs_belf=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
-$as_echo "$lt_cv_cc_needs_belf" >&6; }
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
- # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-esac
-
-need_locks="$enable_libtool_lock"
-
-
- case $host_os in
- rhapsody* | darwin*)
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
-set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$DSYMUTIL"; then
- ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-DSYMUTIL=$ac_cv_prog_DSYMUTIL
-if test -n "$DSYMUTIL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
-$as_echo "$DSYMUTIL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_DSYMUTIL"; then
- ac_ct_DSYMUTIL=$DSYMUTIL
- # Extract the first word of "dsymutil", so it can be a program name with args.
-set dummy dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_DSYMUTIL"; then
- ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
-if test -n "$ac_ct_DSYMUTIL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
-$as_echo "$ac_ct_DSYMUTIL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_DSYMUTIL" = x; then
- DSYMUTIL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- DSYMUTIL=$ac_ct_DSYMUTIL
- fi
-else
- DSYMUTIL="$ac_cv_prog_DSYMUTIL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
-set dummy ${ac_tool_prefix}nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NMEDIT+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NMEDIT"; then
- ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-NMEDIT=$ac_cv_prog_NMEDIT
-if test -n "$NMEDIT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
-$as_echo "$NMEDIT" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_NMEDIT"; then
- ac_ct_NMEDIT=$NMEDIT
- # Extract the first word of "nmedit", so it can be a program name with args.
-set dummy nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_NMEDIT"; then
- ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_NMEDIT="nmedit"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
-if test -n "$ac_ct_NMEDIT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
-$as_echo "$ac_ct_NMEDIT" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_NMEDIT" = x; then
- NMEDIT=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- NMEDIT=$ac_ct_NMEDIT
- fi
-else
- NMEDIT="$ac_cv_prog_NMEDIT"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
-set dummy ${ac_tool_prefix}lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_LIPO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$LIPO"; then
- ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-LIPO=$ac_cv_prog_LIPO
-if test -n "$LIPO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
-$as_echo "$LIPO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_LIPO"; then
- ac_ct_LIPO=$LIPO
- # Extract the first word of "lipo", so it can be a program name with args.
-set dummy lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_LIPO"; then
- ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_LIPO="lipo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
-if test -n "$ac_ct_LIPO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
-$as_echo "$ac_ct_LIPO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_LIPO" = x; then
- LIPO=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- LIPO=$ac_ct_LIPO
- fi
-else
- LIPO="$ac_cv_prog_LIPO"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
-set dummy ${ac_tool_prefix}otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OTOOL"; then
- ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OTOOL=$ac_cv_prog_OTOOL
-if test -n "$OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OTOOL"; then
- ac_ct_OTOOL=$OTOOL
- # Extract the first word of "otool", so it can be a program name with args.
-set dummy otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OTOOL"; then
- ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OTOOL="otool"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
-if test -n "$ac_ct_OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
-$as_echo "$ac_ct_OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OTOOL" = x; then
- OTOOL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OTOOL=$ac_ct_OTOOL
- fi
-else
- OTOOL="$ac_cv_prog_OTOOL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
-set dummy ${ac_tool_prefix}otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OTOOL64"; then
- ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OTOOL64=$ac_cv_prog_OTOOL64
-if test -n "$OTOOL64"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
-$as_echo "$OTOOL64" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OTOOL64"; then
- ac_ct_OTOOL64=$OTOOL64
- # Extract the first word of "otool64", so it can be a program name with args.
-set dummy otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OTOOL64"; then
- ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OTOOL64="otool64"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
-if test -n "$ac_ct_OTOOL64"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
-$as_echo "$ac_ct_OTOOL64" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OTOOL64" = x; then
- OTOOL64=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OTOOL64=$ac_ct_OTOOL64
- fi
-else
- OTOOL64="$ac_cv_prog_OTOOL64"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
-$as_echo_n "checking for -single_module linker flag... " >&6; }
-if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- rm -rf libconftest.dylib*
- echo "int foo(void){return 1;}" > conftest.c
- echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
--dynamiclib -Wl,-single_module conftest.c" >&5
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
- _lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
- lt_cv_apple_cc_single_mod=yes
- else
- cat conftest.err >&5
- fi
- rm -rf libconftest.dylib*
- rm -f conftest.*
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
-$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
-$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
-if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_exported_symbols_list=no
- save_LDFLAGS=$LDFLAGS
- echo "_main" > conftest.sym
- LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- lt_cv_ld_exported_symbols_list=yes
-else
- lt_cv_ld_exported_symbols_list=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
-$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
-$as_echo_n "checking for -force_load linker flag... " >&6; }
-if test "${lt_cv_ld_force_load+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_force_load=no
- cat > conftest.c << _LT_EOF
-int forced_loaded() { return 2;}
-_LT_EOF
- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
- echo "$AR cru libconftest.a conftest.o" >&5
- $AR cru libconftest.a conftest.o 2>&5
- cat > conftest.c << _LT_EOF
-int main() { return 0;}
-_LT_EOF
- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
- _lt_result=$?
- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
- lt_cv_ld_force_load=yes
- else
- cat conftest.err >&5
- fi
- rm -f conftest.err libconftest.a conftest conftest.c
- rm -rf conftest.dSYM
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
-$as_echo "$lt_cv_ld_force_load" >&6; }
- case $host_os in
- rhapsody* | darwin1.[012])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*) # darwin 5.x on
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[012]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
- _lt_dsymutil='~$DSYMUTIL $lib || :'
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in dlfcn.h
-do :
- ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
-"
-if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_DLFCN_H 1
-_ACEOF
-
-fi
-
-done
-
-
-
-
-
-# Set options
-
-
-
-
- enable_win32_dll=no
-
-
- # Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then :
- enableval=$enable_shared; p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_shared=yes
-fi
-
-
-
-
-
-
-
-
-
- # Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then :
- enableval=$enable_static; p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_static=yes
-fi
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-pic was given.
-if test "${with_pic+set}" = set; then :
- withval=$with_pic; pic_mode="$withval"
-else
- pic_mode=default
-fi
-
-
-test -z "$pic_mode" && pic_mode=default
-
-
-
-
-
-
-
- # Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then :
- enableval=$enable_fast_install; p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_fast_install=yes
-fi
-
-
-
-
-
-
-
-
-
-
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ltmain"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-test -z "$LN_S" && LN_S="ln -s"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
-$as_echo_n "checking for objdir... " >&6; }
-if test "${lt_cv_objdir+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
-$as_echo "$lt_cv_objdir" >&6; }
-objdir=$lt_cv_objdir
-
-
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define LT_OBJDIR "$lt_cv_objdir/"
-_ACEOF
-
-
-
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Global variables:
-ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$LD" && LD=ld
-test -z "$ac_objext" && ac_objext=o
-
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-
-
-# Only perform the check for file, if the check method requires it
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
-$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/${ac_tool_prefix}file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-
-
-
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
-$as_echo_n "checking for file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- else
- MAGIC_CMD=:
- fi
-fi
-
- fi
- ;;
-esac
-
-# Use C for the default configuration in the libtool script
-
-lt_save_CC="$CC"
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-objext=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-# Save the default compiler, since it gets overwritten when the other
-# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
-compiler_DEFAULT=$CC
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$RM conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$RM -r conftest*
-
-
-## CAVEAT EMPTOR:
-## There is no encapsulation within the following macros, do not change
-## the running order or otherwise move them around unless you know exactly
-## what you are doing...
-if test -n "$compiler"; then
-
-lt_prog_compiler_no_builtin_flag=
-
-if test "$GCC" = yes; then
- case $cc_basename in
- nvcc*)
- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
- *)
- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-
-
-
-
-
- lt_prog_compiler_wl=
-lt_prog_compiler_pic=
-lt_prog_compiler_static=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_static='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- fi
- lt_prog_compiler_pic='-fPIC'
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- lt_prog_compiler_pic='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic='-fno-common'
- ;;
-
- haiku*)
- # PIC is the default for Haiku.
- # The "-static" flag exists, but is broken.
- lt_prog_compiler_static=
- ;;
-
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- ;;
-
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared=no
- enable_shared=no
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic='-fPIC -shared'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic=-Kconform_pic
- fi
- ;;
-
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
-
- case $cc_basename in
- nvcc*) # Cuda Compiler Driver 2.2
- lt_prog_compiler_wl='-Xlinker '
- lt_prog_compiler_pic='-Xcompiler -fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- else
- lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- # old Intel for x86_64 which still supported -KPIC.
- ecc*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-static'
- ;;
- # icc used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- icc* | ifort*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fPIC'
- lt_prog_compiler_static='-static'
- ;;
- # Lahey Fortran 8.1.
- lf95*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='--shared'
- lt_prog_compiler_static='--static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fpic'
- lt_prog_compiler_static='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
- xl* | bgxl* | bgf* | mpixl*)
- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-qpic'
- lt_prog_compiler_static='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ F* | *Sun*Fortran*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl=''
- ;;
- *Sun\ C*)
- # Sun C 5.9
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl='-Wl,'
- ;;
- esac
- ;;
- esac
- ;;
-
- newsos6)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic='-fPIC -shared'
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- rdos*)
- lt_prog_compiler_static='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl='-Qoption ld ';;
- *)
- lt_prog_compiler_wl='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl='-Qoption ld '
- lt_prog_compiler_pic='-PIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic='-Kconform_pic'
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_can_build_shared=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic='-pic'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared=no
- ;;
- esac
- fi
-
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic=
- ;;
- *)
- lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
-$as_echo "$lt_prog_compiler_pic" >&6; }
-
-
-
-
-
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_pic_works=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
-$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
- case $lt_prog_compiler_pic in
- "" | " "*) ;;
- *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
- esac
-else
- lt_prog_compiler_pic=
- lt_prog_compiler_can_build_shared=no
-fi
-
-fi
-
-
-
-
-
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works=yes
- fi
- else
- lt_cv_prog_compiler_static_works=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
-$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works" = xyes; then
- :
-else
- lt_prog_compiler_static=
-fi
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-
-
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
-$as_echo_n "checking if we can lock with hard links... " >&6; }
- hard_links=yes
- $RM conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
-$as_echo "$hard_links" >&6; }
- if test "$hard_links" = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
-
- runpath_var=
- allow_undefined_flag=
- always_export_symbols=no
- archive_cmds=
- archive_expsym_cmds=
- compiler_needs_object=no
- enable_shared_with_static_runtimes=no
- export_dynamic_flag_spec=
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- hardcode_automatic=no
- hardcode_direct=no
- hardcode_direct_absolute=no
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld=
- hardcode_libdir_separator=
- hardcode_minus_L=no
- hardcode_shlibpath_var=unsupported
- inherit_rpath=no
- link_all_deplibs=unknown
- module_cmds=
- module_expsym_cmds=
- old_archive_from_new_cmds=
- old_archive_from_expsyms_cmds=
- thread_safe_flag_spec=
- whole_archive_flag_spec=
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
- extract_expsyms_cmds=
-
- case $host_os in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs=yes
-
- # On some targets, GNU ld is compatible enough with the native linker
- # that we're better off using the native interface for both.
- lt_use_gnu_ld_interface=no
- if test "$with_gnu_ld" = yes; then
- case $host_os in
- aix*)
- # The AIX port of GNU ld has always aspired to compatibility
- # with the native linker. However, as the warning in the GNU ld
- # block says, versions before 2.19.5* couldn't really create working
- # shared libraries, regardless of the interface used.
- case `$LD -v 2>&1` in
- *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
- *\ \(GNU\ Binutils\)\ [3-9]*) ;;
- *)
- lt_use_gnu_ld_interface=yes
- ;;
- esac
- ;;
- *)
- lt_use_gnu_ld_interface=yes
- ;;
- esac
- fi
-
- if test "$lt_use_gnu_ld_interface" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>&1` in
- *GNU\ gold*) supports_anon_versioning=yes ;;
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.19, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to install binutils
-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
-*** You will then need to restart the configuration process.
-
-_LT_EOF
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds=''
- ;;
- m68k)
- archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- esac
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- export_dynamic_flag_spec='${wl}--export-all-symbols'
- allow_undefined_flag=unsupported
- always_export_symbols=no
- enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- haiku*)
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- link_all_deplibs=yes
- ;;
-
- interix[3-9]*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
- tmp_diet=no
- if test "$host_os" = linux-dietlibc; then
- case $cc_basename in
- diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
- esac
- fi
- if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test "$tmp_diet" = no
- then
- tmp_addflag=
- tmp_sharedflag='-shared'
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95* | pgfortran*)
- # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- lf95*) # Lahey Fortran 8.1
- whole_archive_flag_spec=
- tmp_sharedflag='--shared' ;;
- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
- tmp_sharedflag='-qmkshrobj'
- tmp_addflag= ;;
- nvcc*) # Cuda Compiler Driver 2.2
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- compiler_needs_object=yes
- ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- compiler_needs_object=yes
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- esac
- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
-
- case $cc_basename in
- xlf* | bgf* | bgxlf* | mpixlf*)
- # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
- whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld='-rpath $libdir'
- archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
- fi
- ;;
- esac
- else
- ld_shlibs=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- *)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs" = no; then
- runpath_var=
- hardcode_libdir_flag_spec=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag=unsupported
- always_export_symbols=yes
- archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- # Also, AIX nm treats weak defined symbols like other global
- # defined symbols, whereas GNU nm marks them as "W".
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds=''
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- file_list_spec='${wl}-f,'
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- export_dynamic_flag_spec='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='-berok'
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag=' ${wl}-bernotok'
- allow_undefined_flag=' ${wl}-berok'
- if test "$with_gnu_ld" = yes; then
- # We only use this code for GNU lds that support --whole-archive.
- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- else
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec='$convenience'
- fi
- archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds=''
- ;;
- m68k)
- archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- esac
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_from_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes=yes
- ;;
-
- darwin* | rhapsody*)
-
-
- archive_cmds_need_lc=no
- hardcode_direct=no
- hardcode_automatic=yes
- hardcode_shlibpath_var=unsupported
- if test "$lt_cv_ld_force_load" = "yes"; then
- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
- else
- whole_archive_flag_spec=''
- fi
- link_all_deplibs=yes
- allow_undefined_flag="$_lt_dar_allow_undefined"
- case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
- *) _lt_dar_can_shared=$GCC ;;
- esac
- if test "$_lt_dar_can_shared" = "yes"; then
- output_verbose_link_cmd=func_echo_all
- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-
- else
- ld_shlibs=no
- fi
-
- ;;
-
- dgux*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2.*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- export_dynamic_flag_spec='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes && test "$with_gnu_ld" = no; then
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_flag_spec_ld='+b $libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- export_dynamic_flag_spec='${wl}-E'
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes && test "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
-
- # Older versions of the 11.00 compiler do not understand -b yet
- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
-$as_echo_n "checking if $CC understands -b... " >&6; }
-if test "${lt_cv_prog_compiler__b+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler__b=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -b"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler__b=yes
- fi
- else
- lt_cv_prog_compiler__b=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
-$as_echo "$lt_cv_prog_compiler__b" >&6; }
-
-if test x"$lt_cv_prog_compiler__b" = xyes; then
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
-else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
-fi
-
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- ;;
- *)
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- # Try to use the -exported_symbol ld option, if it does not
- # work, assume that -exports_file does not work either and
- # implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-int foo(void) {}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- inherit_rpath=yes
- link_all_deplibs=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- newsos6)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_shlibpath_var=no
- ;;
-
- *nto* | *qnx*)
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- hardcode_direct_absolute=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_separator=:
- ;;
-
- solaris*)
- no_undefined_flag=' -z defs'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- else
- case `$CC -V 2>&1` in
- *"Compilers 5.0"*)
- wlarc=''
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
- ;;
- *)
- wlarc='${wl}'
- archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- ;;
- esac
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_shlibpath_var=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- link_all_deplibs=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds='$CC -r -o $output$reload_objs'
- hardcode_direct=no
- ;;
- motorola)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4.3*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag='${wl}-z,text'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag='${wl}-z,text'
- allow_undefined_flag='${wl}-z,nodefs'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-R,$libdir'
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- export_dynamic_flag_spec='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- *)
- ld_shlibs=no
- ;;
- esac
-
- if test x$host_vendor = xsni; then
- case $host in
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- ;;
- esac
- fi
- fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
-$as_echo "$ld_shlibs" >&6; }
-test "$ld_shlibs" = no && can_build_shared=no
-
-with_gnu_ld=$with_gnu_ld
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
-$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl
- pic_flag=$lt_prog_compiler_pic
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
- (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- then
- lt_cv_archive_cmds_need_lc=no
- else
- lt_cv_archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
- ;;
- esac
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
-$as_echo_n "checking dynamic linker characteristics... " >&6; }
-
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- case $host_os in
- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
- *) lt_sed_strip_eq="s,=/,/,g" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
- case $lt_search_path_spec in
- *\;*)
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
- ;;
- *)
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
- ;;
- esac
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[lt_foo]++; }
- if (lt_freq[lt_foo] == 1) { print lt_foo; }
-}'`
- # AWK program above erroneously prepends '/' to C:/dos/paths
- # for these hosts.
- case $host_os in
- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
- $SED 's,/\([A-Za-z]:\),\1,g'` ;;
- esac
- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- case $host_cpu in
- powerpc)
- # Since July 2007 AmigaOS4 officially supports .so libraries.
- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- ;;
- m68k)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
- esac
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32* | cegcc*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
-
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
- ;;
- mingw* | cegcc*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[23].*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2.*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-haiku*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- dynamic_linker="$host_os runtime_loader"
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
- postinstall_cmds='chmod 555 $lib'
- # or fails outright, so override atomically:
- install_override_mode=555
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
-
- # Some binutils ld are patched to set DT_RUNPATH
- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_shlibpath_overrides_runpath=no
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
- lt_cv_shlibpath_overrides_runpath=yes
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
-
-fi
-
- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-*nto* | *qnx*)
- version_type=qnx
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='ldqnx.so'
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-tpf*)
- # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
-$as_echo "$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
-$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" ||
- test -n "$runpath_var" ||
- test "X$hardcode_automatic" = "Xyes" ; then
-
- # We can hardcode non-existent directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
-$as_echo "$hardcode_action" >&6; }
-
-if test "$hardcode_action" = relink ||
- test "$inherit_rpath" = yes; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-
-
-
-
- if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32* | cegcc*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dl_dlopen=yes
-else
- ac_cv_lib_dl_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
-if test "x$ac_cv_func_shl_load" = x""yes; then :
- lt_cv_dlopen="shl_load"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
-$as_echo_n "checking for shl_load in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shl_load ();
-int
-main ()
-{
-return shl_load ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dld_shl_load=yes
-else
- ac_cv_lib_dld_shl_load=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
-$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
-else
- ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dl_dlopen=yes
-else
- ac_cv_lib_dl_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
-$as_echo_n "checking for dlopen in -lsvld... " >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_svld_dlopen=yes
-else
- ac_cv_lib_svld_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
-$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
-if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
-$as_echo_n "checking for dld_link in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dld_link ();
-int
-main ()
-{
-return dld_link ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dld_dld_link=yes
-else
- ac_cv_lib_dld_dld_link=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
-$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
-if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
-$as_echo_n "checking whether a program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-#line 10408 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* When -fvisbility=hidden is used, assume the code has been annotated
- correspondingly for the symbols needed. */
-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
-void fnord () __attribute__((visibility("default")));
-#endif
-
-void fnord () { int i=42; }
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else
- {
- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- else puts (dlerror ());
- }
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}
-_LT_EOF
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
-$as_echo "$lt_cv_dlopen_self" >&6; }
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
-$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-#line 10514 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* When -fvisbility=hidden is used, assume the code has been annotated
- correspondingly for the symbols needed. */
-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
-void fnord () __attribute__((visibility("default")));
-#endif
-
-void fnord () { int i=42; }
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else
- {
- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- else puts (dlerror ());
- }
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}
-_LT_EOF
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
-$as_echo "$lt_cv_dlopen_self_static" >&6; }
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-striplib=
-old_striplib=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
-$as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- fi
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- ;;
- esac
-fi
-
-
-
-
-
-
-
-
-
-
-
-
- # Report which library types will actually be built
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
-$as_echo_n "checking if libtool supports shared libraries... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
-$as_echo "$can_build_shared" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
-$as_echo_n "checking whether to build shared libraries... " >&6; }
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
-$as_echo "$enable_shared" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
-$as_echo_n "checking whether to build static libraries... " >&6; }
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
-$as_echo "$enable_static" >&6; }
-
-
-
-
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
-
-
-
-
-
-
-
-
-
-
-
-
- ac_config_commands="$ac_config_commands libtool"
-
-
-
-
-# Only expand once:
-
-
-
-
-
-CC_FOR_BUILD=${CC_FOR_BUILD:-gcc}
-
-
-for ac_prog in gawk mawk nawk awk
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AWK="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-
-WARN_FLAGS='-Wall -Wextra -Wwrite-strings -Wcast-qual'
-
-
-WERROR="-Werror"
-
-
-# See if the user wants to configure without libffi. Some
-# architectures don't support it. FIXME: We should set a default
-# based on the host.
-
-# Check whether --with-libffi was given.
-if test "${with_libffi+set}" = set; then :
- withval=$with_libffi; :
-else
- with_libffi=${with_libffi_default-yes}
-fi
-
-
-LIBFFI=
-LIBFFIINCS=
-if test "$with_libffi" != no; then
-
-$as_echo "#define USE_LIBFFI 1" >>confdefs.h
-
- LIBFFI=../libffi/libffi_convenience.la
- LIBFFIINCS='-I$(top_srcdir)/../libffi/include -I../libffi/include'
-fi
-
-
-
-MATH_LIBS=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
-$as_echo_n "checking for sqrt in -lm... " >&6; }
-if test "${ac_cv_lib_m_sqrt+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char sqrt ();
-int
-main ()
-{
-return sqrt ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_m_sqrt=yes
-else
- ac_cv_lib_m_sqrt=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5
-$as_echo "$ac_cv_lib_m_sqrt" >&6; }
-if test "x$ac_cv_lib_m_sqrt" = x""yes; then :
- MATH_LIBS=-lm
-fi
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is supported" >&5
-$as_echo_n "checking whether -pthread is supported... " >&6; }
-if test "${libgpython_cv_lib_pthread+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- CFLAGS_hold=$CFLAGS
-CFLAGS="$CFLAGS -pthread"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-int i;
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- libgpython_cv_lib_pthread=yes
-else
- libgpython_cv_lib_pthread=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-CFLAGS=$CFLAGS_hold
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgpython_cv_lib_pthread" >&5
-$as_echo "$libgpython_cv_lib_pthread" >&6; }
-PTHREAD_CFLAGS=
-if test "$libgpython_cv_lib_pthread" = yes; then
- PTHREAD_CFLAGS=-pthread
-fi
-
-
-PTHREAD_LIBS=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
-$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
-if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpthread $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_create ();
-int
-main ()
-{
-return pthread_create ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_pthread_pthread_create=yes
-else
- ac_cv_lib_pthread_pthread_create=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5
-$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
-if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then :
- PTHREAD_LIBS=-lpthread
-fi
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
-$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_c_bigendian=unknown
- # See if we're dealing with a universal compiler.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef __APPLE_CC__
- not a universal capable compiler
- #endif
- typedef int dummy;
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
- # Check for potential -arch flags. It is not universal unless
- # there are at least two -arch flags with different values.
- ac_arch=
- ac_prev=
- for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
- if test -n "$ac_prev"; then
- case $ac_word in
- i?86 | x86_64 | ppc | ppc64)
- if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
- ac_arch=$ac_word
- else
- ac_cv_c_bigendian=universal
- break
- fi
- ;;
- esac
- ac_prev=
- elif test "x$ac_word" = "x-arch"; then
- ac_prev=arch
- fi
- done
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $ac_cv_c_bigendian = unknown; then
- # See if sys/param.h defines the BYTE_ORDER macro.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- #include <sys/param.h>
-
-int
-main ()
-{
-#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
- && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
- && LITTLE_ENDIAN)
- bogus endian macros
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- # It does; now see whether it defined to BIG_ENDIAN or not.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- #include <sys/param.h>
-
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_bigendian=yes
-else
- ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test $ac_cv_c_bigendian = unknown; then
- # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
-
-int
-main ()
-{
-#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
- bogus endian macros
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- # It does; now see whether it defined to _BIG_ENDIAN or not.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
-
-int
-main ()
-{
-#ifndef _BIG_ENDIAN
- not big endian
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_bigendian=yes
-else
- ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test $ac_cv_c_bigendian = unknown; then
- # Compile a test program.
- if test "$cross_compiling" = yes; then :
- # Try to guess by grepping values from an object file.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-short int ascii_mm[] =
- { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
- short int ascii_ii[] =
- { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
- int use_ascii (int i) {
- return ascii_mm[i] + ascii_ii[i];
- }
- short int ebcdic_ii[] =
- { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
- short int ebcdic_mm[] =
- { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
- int use_ebcdic (int i) {
- return ebcdic_mm[i] + ebcdic_ii[i];
- }
- extern int foo;
-
-int
-main ()
-{
-return use_ascii (foo) == use_ebcdic (foo);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
- ac_cv_c_bigendian=yes
- fi
- if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
- if test "$ac_cv_c_bigendian" = unknown; then
- ac_cv_c_bigendian=no
- else
- # finding both strings is unlikely to happen, but who knows?
- ac_cv_c_bigendian=unknown
- fi
- fi
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
- /* Are we little or big endian? From Harbison&Steele. */
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
- u.l = 1;
- return u.c[sizeof (long int) - 1] == 1;
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_c_bigendian=no
-else
- ac_cv_c_bigendian=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
-$as_echo "$ac_cv_c_bigendian" >&6; }
- case $ac_cv_c_bigendian in #(
- yes)
- $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
-;; #(
- no)
- ;; #(
- universal)
-
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
-
- ;; #(
- *)
- as_fn_error "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
- esac
-
-
-GCC_CHECK_UNWIND_GETIPINFO
-
-
-
-
-# Checks for header files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
-$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
-if test "${ac_cv_header_stdbool_h+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <stdbool.h>
-#ifndef bool
- "error: bool is not defined"
-#endif
-#ifndef false
- "error: false is not defined"
-#endif
-#if false
- "error: false is not 0"
-#endif
-#ifndef true
- "error: true is not defined"
-#endif
-#if true != 1
- "error: true is not 1"
-#endif
-#ifndef __bool_true_false_are_defined
- "error: __bool_true_false_are_defined is not defined"
-#endif
-
- struct s { _Bool s: 1; _Bool t; } s;
-
- char a[true == 1 ? 1 : -1];
- char b[false == 0 ? 1 : -1];
- char c[__bool_true_false_are_defined == 1 ? 1 : -1];
- char d[(bool) 0.5 == true ? 1 : -1];
- bool e = &s;
- char f[(_Bool) 0.0 == false ? 1 : -1];
- char g[true];
- char h[sizeof (_Bool)];
- char i[sizeof s.t];
- enum { j = false, k = true, l = false * true, m = true * 256 };
- /* The following fails for
- HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
- _Bool n[m];
- char o[sizeof n == m * sizeof n[0] ? 1 : -1];
- char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
-# if defined __xlc__ || defined __GNUC__
- /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
- reported by James Lemley on 2005-10-05; see
- http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
- This test is not quite right, since xlc is allowed to
- reject this program, as the initializer for xlcbug is
- not one of the forms that C requires support for.
- However, doing the test right would require a runtime
- test, and that would make cross-compilation harder.
- Let us hope that IBM fixes the xlc bug, and also adds
- support for this kind of constant expression. In the
- meantime, this test will reject xlc, which is OK, since
- our stdbool.h substitute should suffice. We also test
- this with GCC, where it should work, to detect more
- quickly whether someone messes up the test in the
- future. */
- char digs[] = "0123456789";
- int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
-# endif
- /* Catch a bug in an HP-UX C compiler. See
- http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
- http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
- */
- _Bool q = true;
- _Bool *pq = &q;
-
-int
-main ()
-{
-
- *pq |= q;
- *pq |= ! q;
- /* Refer to every declared value, to avoid compiler optimizations. */
- return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
- + !m + !n + !o + !p + !q + !pq);
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdbool_h=yes
-else
- ac_cv_header_stdbool_h=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
-$as_echo "$ac_cv_header_stdbool_h" >&6; }
-ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
-if test "x$ac_cv_type__Bool" = x""yes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE__BOOL 1
-_ACEOF
-
-
-fi
-
-if test $ac_cv_header_stdbool_h = yes; then
-
-$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-for ac_header in stdlib.h string.h stdarg.h unistd.h \
- stdint.h stdio.h getopt.h \
- assert.h sys/types.h signal.h \
- fcntl.h pthread.h sys/wait.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-# Checks for typedefs, structures, and compiler characteristics.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
-$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
-if test "${ac_cv_c_const+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-/* FIXME: Include the comments suggested by Paul. */
-#ifndef __cplusplus
- /* Ultrix mips cc rejects this. */
- typedef int charset[2];
- const charset cs;
- /* SunOS 4.1.1 cc rejects this. */
- char const *const *pcpcc;
- char **ppc;
- /* NEC SVR4.0.2 mips cc rejects this. */
- struct point {int x, y;};
- static struct point const zero = {0,0};
- /* AIX XL C 1.02.0.0 rejects this.
- It does not let you subtract one const X* pointer from another in
- an arm of an if-expression whose if-part is not a constant
- expression */
- const char *g = "string";
- pcpcc = &g + (g ? g-g : 0);
- /* HPUX 7.0 cc rejects these. */
- ++pcpcc;
- ppc = (char**) pcpcc;
- pcpcc = (char const *const *) ppc;
- { /* SCO 3.2v4 cc rejects this. */
- char *t;
- char const *s = 0 ? (char *) 0 : (char const *) 0;
-
- *t++ = 0;
- if (s) return 0;
- }
- { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
- int x[] = {25, 17};
- const int *foo = &x[0];
- ++foo;
- }
- { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
- typedef const int *iptr;
- iptr p = 0;
- ++p;
- }
- { /* AIX XL C 1.02.0.0 rejects this saying
- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
- }
- { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
- const int foo = 10;
- if (!foo) return 0;
- }
- return !cs[0] && !zero.x;
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_const=yes
-else
- ac_cv_c_const=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
-$as_echo "$ac_cv_c_const" >&6; }
-if test $ac_cv_c_const = no; then
-
-$as_echo "#define const /**/" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
-_ACEOF
-
-fi
-
-ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
-
-fi
-
-for ac_func in popen fopen fclose sprintf fprintf strdup \
- strlen strcpy strcmp getopt_long \
- memcpy calloc system sysconf atoi \
- getpid execl fork wait exit atof \
- vfprintf memcmp getc fgets pipe \
- waitpid fdopen
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-# Checks for library functions.
-for ac_header in stdlib.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_stdlib_h" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_STDLIB_H 1
-_ACEOF
-
-fi
-
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
-$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
-if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- ac_cv_func_malloc_0_nonnull=no
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#if defined STDC_HEADERS || defined HAVE_STDLIB_H
-# include <stdlib.h>
-#else
-char *malloc ();
-#endif
-
-int
-main ()
-{
-return ! malloc (0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_func_malloc_0_nonnull=yes
-else
- ac_cv_func_malloc_0_nonnull=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
-$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
-if test $ac_cv_func_malloc_0_nonnull = yes; then :
-
-$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
-
-else
- $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
-
- case " $LIBOBJS " in
- *" malloc.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
- ;;
-esac
-
-
-$as_echo "#define malloc rpl_malloc" >>confdefs.h
-
-fi
-
-
-
-
-
- for ac_header in $ac_header_list
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether utime accepts a null argument" >&5
-$as_echo_n "checking whether utime accepts a null argument... " >&6; }
-if test "${ac_cv_func_utime_null+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- rm -f conftest.data; >conftest.data
-# Sequent interprets utime(file, 0) to mean use start of epoch. Wrong.
-if test "$cross_compiling" = yes; then :
- ac_cv_func_utime_null='guessing yes'
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
- #ifdef HAVE_UTIME_H
- # include <utime.h>
- #endif
-int
-main ()
-{
-struct stat s, t;
- return ! (stat ("conftest.data", &s) == 0
- && utime ("conftest.data", 0) == 0
- && stat ("conftest.data", &t) == 0
- && t.st_mtime >= s.st_mtime
- && t.st_mtime - s.st_mtime < 120);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_func_utime_null=yes
-else
- ac_cv_func_utime_null=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_utime_null" >&5
-$as_echo "$ac_cv_func_utime_null" >&6; }
-if test "x$ac_cv_func_utime_null" != xno; then
- ac_cv_func_utime_null=yes
-
-$as_echo "#define HAVE_UTIME_NULL 1" >>confdefs.h
-
-fi
-rm -f conftest.data
-
-for ac_func in vprintf
-do :
- ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
-if test "x$ac_cv_func_vprintf" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_VPRINTF 1
-_ACEOF
-
-ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
-if test "x$ac_cv_func__doprnt" = x""yes; then :
-
-$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
-
-fi
-
-fi
-done
-
-
-
-ac_config_files="$ac_config_files Makefile"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes: double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \.
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
- if test -n "$EXEEXT"; then
- am__EXEEXT_TRUE=
- am__EXEEXT_FALSE='#'
-else
- am__EXEEXT_TRUE='#'
- am__EXEEXT_FALSE=
-fi
-
-if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
- as_fn_error "conditional \"AMDEP\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
- as_fn_error "conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
- as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-
-
-: ${CONFIG_STATUS=./config.status}
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
- fi
- $as_echo "$as_me: error: $1" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by GCC-Rust-runtime $as_me 0.1, which was
-generated by GNU Autoconf 2.64. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-case $ac_config_files in *"
-"*) set x $ac_config_files; shift; ac_config_files=$*;;
-esac
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration. Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- -q, --quiet, --silent
- do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
- --header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
-
-Configuration files:
-$config_files
-
-Configuration headers:
-$config_headers
-
-Configuration commands:
-$config_commands
-
-Report bugs to <http://gcc.gnu.org>.
-GCC-Rust-runtime home page: <https://github.com/redbrain/gccrs>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_version="\\
-GCC-Rust-runtime config.status 0.1
-configured by $0, generated by GNU Autoconf 2.64,
- with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2009 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-INSTALL='$INSTALL'
-MKDIR_P='$MKDIR_P'
-AWK='$AWK'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- $as_echo "$ac_cs_version"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append CONFIG_FILES " '$ac_optarg'"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append CONFIG_HEADERS " '$ac_optarg'"
- ac_need_defaults=false;;
- --he | --h)
- # Conflict between --help and --header
- as_fn_error "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
- --help | --hel | -h )
- $as_echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) as_fn_error "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
- *) as_fn_append ac_config_targets " $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
- shift
- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
- CONFIG_SHELL='$SHELL'
- export CONFIG_SHELL
- exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-#
-# INIT-COMMANDS
-#
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
-
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-sed_quote_subst='$sed_quote_subst'
-double_quote_subst='$double_quote_subst'
-delay_variable_subst='$delay_variable_subst'
-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
-
-LTCC='$LTCC'
-LTCFLAGS='$LTCFLAGS'
-compiler='$compiler_DEFAULT'
-
-# A function that is used when there is no print builtin or printf.
-func_fallback_echo ()
-{
- eval 'cat <<_LTECHO_EOF
-\$1
-_LTECHO_EOF'
-}
-
-# Quote evaled strings.
-for var in SED \
-GREP \
-EGREP \
-FGREP \
-SHELL \
-ECHO \
-LD \
-NM \
-LN_S \
-lt_SP2NL \
-lt_NL2SP \
-reload_flag \
-OBJDUMP \
-deplibs_check_method \
-file_magic_cmd \
-AR \
-AR_FLAGS \
-STRIP \
-RANLIB \
-CC \
-CFLAGS \
-compiler \
-lt_cv_sys_global_symbol_pipe \
-lt_cv_sys_global_symbol_to_cdecl \
-lt_cv_sys_global_symbol_to_c_name_address \
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-lt_prog_compiler_no_builtin_flag \
-lt_prog_compiler_wl \
-lt_prog_compiler_pic \
-lt_prog_compiler_static \
-lt_cv_prog_compiler_c_o \
-need_locks \
-DSYMUTIL \
-NMEDIT \
-LIPO \
-OTOOL \
-OTOOL64 \
-shrext_cmds \
-export_dynamic_flag_spec \
-whole_archive_flag_spec \
-compiler_needs_object \
-with_gnu_ld \
-allow_undefined_flag \
-no_undefined_flag \
-hardcode_libdir_flag_spec \
-hardcode_libdir_flag_spec_ld \
-hardcode_libdir_separator \
-fix_srcfile_path \
-exclude_expsyms \
-include_expsyms \
-file_list_spec \
-variables_saved_for_relink \
-libname_spec \
-library_names_spec \
-soname_spec \
-install_override_mode \
-finish_eval \
-old_striplib \
-striplib; do
- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
- *[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-# Double-quote double-evaled strings.
-for var in reload_cmds \
-old_postinstall_cmds \
-old_postuninstall_cmds \
-old_archive_cmds \
-extract_expsyms_cmds \
-old_archive_from_new_cmds \
-old_archive_from_expsyms_cmds \
-archive_cmds \
-archive_expsym_cmds \
-module_cmds \
-module_expsym_cmds \
-export_symbols_cmds \
-prelink_cmds \
-postinstall_cmds \
-postuninstall_cmds \
-finish_cmds \
-sys_lib_search_path_spec \
-sys_lib_dlsearch_path_spec; do
- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
- *[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
- ;;
- *)
- eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
- ;;
- esac
-done
-
-ac_aux_dir='$ac_aux_dir'
-xsi_shell='$xsi_shell'
-lt_shell_append='$lt_shell_append'
-
-# See if we are running on zsh, and set the options which allow our
-# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-
- PACKAGE='$PACKAGE'
- VERSION='$VERSION'
- TIMESTAMP='$TIMESTAMP'
- RM='$RM'
- ofile='$ofile'
-
-
-
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
- "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
- "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-
- *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
- test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp=
- trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
- trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
-
-# Set up the scripts for CONFIG_FILES section.
-# No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with `./config.status config.h'.
-if test -n "$CONFIG_FILES"; then
-
-
-ac_cr=`echo X | tr X '\015'`
-# On cygwin, bash can eat \r inside `` if the user requested igncr.
-# But we know of no other shell where ac_cr would be empty at this
-# point, so we can use a bashism as a fallback.
-if test "x$ac_cr" = x; then
- eval ac_cr=\$\'\\r\'
-fi
-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\r'
-else
- ac_cs_awk_cr=$ac_cr
-fi
-
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
-_ACEOF
-
-
-{
- echo "cat >conf$$subs.awk <<_ACEOF" &&
- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
- echo "_ACEOF"
-} >conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- . ./conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-
- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
- if test $ac_delim_n = $ac_delim_num; then
- break
- elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-rm -f conf$$subs.sh
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
-_ACEOF
-sed -n '
-h
-s/^/S["/; s/!.*/"]=/
-p
-g
-s/^[^!]*!//
-:repl
-t repl
-s/'"$ac_delim"'$//
-t delim
-:nl
-h
-s/\(.\{148\}\).*/\1/
-t more1
-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
-p
-n
-b repl
-:more1
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t nl
-:delim
-h
-s/\(.\{148\}\).*/\1/
-t more2
-s/["\\]/\\&/g; s/^/"/; s/$/"/
-p
-b
-:more2
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t delim
-' <conf$$subs.awk | sed '
-/^[^""]/{
- N
- s/\n//
-}
-' >>$CONFIG_STATUS || ac_write_fail=1
-rm -f conf$$subs.awk
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
- for (key in S) S_is_set[key] = 1
- FS = "\a"
-
-}
-{
- line = $ 0
- nfields = split(line, field, "@")
- substed = 0
- len = length(field[1])
- for (i = 2; i < nfields; i++) {
- key = field[i]
- keylen = length(key)
- if (S_is_set[key]) {
- value = S[key]
- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
- len += length(value) + length(field[++i])
- substed = 1
- } else
- len += 1 + keylen
- }
-
- print line
-}
-
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
-else
- cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error "could not setup config files machinery" "$LINENO" 5
-_ACEOF
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-fi # test -n "$CONFIG_FILES"
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
- ac_t=`sed -n "/$ac_delim/p" confdefs.h`
- if test -z "$ac_t"; then
- break
- elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any. Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[ ]*#[ ]*define[ ][ ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- for (key in D) D_is_set[key] = 1
- FS = "\a"
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
- line = \$ 0
- split(line, arg, " ")
- if (arg[1] == "#") {
- defundef = arg[2]
- mac1 = arg[3]
- } else {
- defundef = substr(arg[1], 2)
- mac1 = arg[2]
- }
- split(mac1, mac2, "(") #)
- macro = mac2[1]
- prefix = substr(line, 1, index(line, defundef) - 1)
- if (D_is_set[macro]) {
- # Preserve the white space surrounding the "#".
- print prefix "define", macro P[macro] D[macro]
- next
- } else {
- # Replace #undef with comments. This is necessary, for example,
- # in the case of _POSIX_SOURCE, which is predefined and required
- # on some systems where configure will not decide to define it.
- if (defundef == "undef") {
- print "/*", prefix defundef, macro, "*/"
- next
- }
- }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
-shift
-for ac_tag
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
- esac
- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
- as_fn_append ac_file_inputs " '$ac_f'"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input='Generated from '`
- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
- `' by configure.'
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
- fi
- # Neutralize special characters interpreted by sed in replacement strings.
- case $configure_input in #(
- *\&* | *\|* | *\\* )
- ac_sed_conf_input=`$as_echo "$configure_input" |
- sed 's/[\\\\&|]/\\\\&/g'`;; #(
- *) ac_sed_conf_input=$configure_input;;
- esac
-
- case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir="$ac_dir"; as_fn_mkdir_p
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
- esac
- ac_MKDIR_P=$MKDIR_P
- case $MKDIR_P in
- [\\/$]* | ?:[\\/]* ) ;;
- */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
- esac
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
-ac_sed_dataroot='
-/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p'
-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_sed_extra="$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s|@configure_input@|$ac_sed_conf_input|;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@top_build_prefix@&$ac_top_build_prefix&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-s&@INSTALL@&$ac_INSTALL&;t t
-s&@MKDIR_P@&$ac_MKDIR_P&;t t
-$ac_datarootdir_hack
-"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&2;}
-
- rm -f "$tmp/stdin"
- case $ac_file in
- -) cat "$tmp/out" && rm -f "$tmp/out";;
- *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
- esac \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- ;;
- :H)
- #
- # CONFIG_HEADER
- #
- if test x"$ac_file" != x-; then
- {
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
- } >"$tmp/config.h" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
- else
- rm -f "$ac_file"
- mv "$tmp/config.h" "$ac_file" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- fi
- else
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error "could not create -" "$LINENO" 5
- fi
-# Compute "$ac_file"'s index in $config_headers.
-_am_arg="$ac_file"
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
-$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$_am_arg" : 'X\(//\)[^/]' \| \
- X"$_am_arg" : 'X\(//\)$' \| \
- X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$_am_arg" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`/stamp-h$_am_stamp_count
- ;;
-
- :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-$as_echo "$as_me: executing $ac_file commands" >&6;}
- ;;
- esac
-
-
- case $ac_file$ac_mode in
- "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$mf" : 'X\(//\)[^/]' \| \
- X"$mf" : 'X\(//\)$' \| \
- X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$file" : 'X\(//\)[^/]' \| \
- X"$file" : 'X\(//\)$' \| \
- X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir=$dirpart/$fdir; as_fn_mkdir_p
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
- ;;
- "libtool":C)
-
- # See if we are running on zsh, and set the options which allow our
- # commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
-
- cfgfile="${ofile}T"
- trap "$RM \"$cfgfile\"; exit 1" 1 2 15
- $RM "$cfgfile"
-
- cat <<_LT_EOF >> "$cfgfile"
-#! $SHELL
-
-# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is part of GNU Libtool.
-#
-# GNU Libtool is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# As a special exception to the GNU General Public License,
-# if you distribute this file as part of a program or library that
-# is built using GNU Libtool, you may include this file under the
-# same distribution terms that you use for the rest of that program.
-#
-# GNU Libtool is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Libtool; see the file COPYING. If not, a copy
-# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
-# obtained by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-
-# The names of the tagged configurations supported by this script.
-available_tags=""
-
-# ### BEGIN LIBTOOL CONFIG
-
-# A sed program that does not truncate output.
-SED=$lt_SED
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="\$SED -e 1s/^X//"
-
-# A grep program that handles long lines.
-GREP=$lt_GREP
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# A literal string matcher.
-FGREP=$lt_FGREP
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# An echo program that protects backslashes.
-ECHO=$lt_ECHO
-
-# Which release of libtool.m4 was used?
-macro_version=$macro_version
-macro_revision=$macro_revision
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# What type of objects to build.
-pic_mode=$pic_mode
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# A BSD- or MS-compatible name lister.
-NM=$lt_NM
-
-# Whether we need soft or hard links.
-LN_S=$lt_LN_S
-
-# What is the maximum length of a command?
-max_cmd_len=$max_cmd_len
-
-# Object file suffix (normally "o").
-objext=$ac_objext
-
-# Executable file suffix (normally "").
-exeext=$exeext
-
-# whether the shell understands "unset".
-lt_unset=$lt_unset
-
-# turn spaces into newlines.
-SP2NL=$lt_lt_SP2NL
-
-# turn newlines into spaces.
-NL2SP=$lt_lt_NL2SP
-
-# An object symbol dumper.
-OBJDUMP=$lt_OBJDUMP
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == "file_magic".
-file_magic_cmd=$lt_file_magic_cmd
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A symbol stripping program.
-STRIP=$lt_STRIP
-
-# Commands used to install an old-style archive.
-RANLIB=$lt_RANLIB
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Whether to use a lock for old archive extraction.
-lock_old_archive_extraction=$lock_old_archive_extraction
-
-# A C compiler.
-LTCC=$lt_CC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_CFLAGS
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration.
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair.
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# Transform the output of nm in a C name address pair when lib prefix is needed.
-global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# Used to examine libraries when file_magic_cmd begins with "file".
-MAGIC_CMD=$MAGIC_CMD
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
-DSYMUTIL=$lt_DSYMUTIL
-
-# Tool to change global to local symbols on Mac OS X.
-NMEDIT=$lt_NMEDIT
-
-# Tool to manipulate fat objects and archives on Mac OS X.
-LIPO=$lt_LIPO
-
-# ldd/readelf like tool for Mach-O binaries on Mac OS X.
-OTOOL=$lt_OTOOL
-
-# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
-OTOOL64=$lt_OTOOL64
-
-# Old archive suffix (normally "a").
-libext=$libext
-
-# Shared library suffix (normally ".so").
-shrext_cmds=$lt_shrext_cmds
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at link time.
-variables_saved_for_relink=$lt_variables_saved_for_relink
-
-# Do we need the "lib" prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Library versioning type.
-version_type=$version_type
-
-# Shared library runtime path variable.
-runpath_var=$runpath_var
-
-# Shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Permission mode override for installation of shared libraries.
-install_override_mode=$lt_install_override_mode
-
-# Command to use after installation of a shared archive.
-postinstall_cmds=$lt_postinstall_cmds
-
-# Command to use after uninstallation of a shared archive.
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# As "finish_cmds", except a single script fragment to be evaled but
-# not shown.
-finish_eval=$lt_finish_eval
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Compile-time system search path for libraries.
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-
-# The linker used to build libraries.
-LD=$lt_LD
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# Commands used to build an old-style archive.
-old_archive_cmds=$lt_old_archive_cmds
-
-# A language specific compiler.
-CC=$lt_compiler
-
-# Is the compiler the GNU compiler?
-with_gcc=$GCC
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc
-
-# Whether or not to disallow shared libs when runtime libs are static.
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec
-
-# Whether the compiler copes with passing no objects directly.
-compiler_needs_object=$lt_compiler_needs_object
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
-
-# Commands used to build a shared archive.
-archive_cmds=$lt_archive_cmds
-archive_expsym_cmds=$lt_archive_expsym_cmds
-
-# Commands used to build a loadable module if different from building
-# a shared archive.
-module_cmds=$lt_module_cmds
-module_expsym_cmds=$lt_module_expsym_cmds
-
-# Whether we are building with GNU ld or not.
-with_gnu_ld=$lt_with_gnu_ld
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag
-
-# Flag that enforces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
-
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking. This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
-# Whether we need a single "-rpath" flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator
-
-# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
-# DIR into the resulting binary.
-hardcode_direct=$hardcode_direct
-
-# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
-# DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
-# library is relocated.
-hardcode_direct_absolute=$hardcode_direct_absolute
-
-# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
-# into the resulting binary.
-hardcode_minus_L=$hardcode_minus_L
-
-# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
-# into the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var
-
-# Set to "yes" if building a shared library automatically hardcodes DIR
-# into the library and all subsequent libraries and executables linked
-# against it.
-hardcode_automatic=$hardcode_automatic
-
-# Set to yes if linker adds runtime paths of dependent libraries
-# to runtime path list.
-inherit_rpath=$inherit_rpath
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to "yes" if exported symbols are required.
-always_export_symbols=$always_export_symbols
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms
-
-# Commands necessary for linking programs (against libraries) with templates.
-prelink_cmds=$lt_prelink_cmds
-
-# Specify filename containing input files.
-file_list_spec=$lt_file_list_spec
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action
-
-# ### END LIBTOOL CONFIG
-
-_LT_EOF
-
- case $host_os in
- aix3*)
- cat <<\_LT_EOF >> "$cfgfile"
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-_LT_EOF
- ;;
- esac
-
-
-ltmain="$ac_aux_dir/ltmain.sh"
-
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- case $xsi_shell in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=${1%%=*}
- func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=$(( $* ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=${#1}
-}
-
-_LT_EOF
- ;;
- *) # Bourne compatible functions.
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result=`$ECHO "${1}" | $SED "$basename"`
-}
-
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
- case ${2} in
- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
- esac
-}
-
-# sed scripts:
-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[^=]*=//'
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=`expr "$@"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
-
-case $lt_shell_append in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$1+=\$2"
-}
-_LT_EOF
- ;;
- *)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$1=\$$1\$2"
-}
-
-_LT_EOF
- ;;
- esac
-
-
- sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" ||
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-
- ;;
-
- esac
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
- as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit $?
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
-
+++ /dev/null
-# Copyright (C) 2013 Free Software Foundation, Inc.
-#
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING3. If not see
-# <http://www.gnu.org/licenses/>.
-
-##############################################################################
-### WARNING: this file contains embedded tabs. Do not run untabify on this file.
-# Process this file with autoconf to produce a configure script, like so:
-# aclocal && autoconf && autoheader && automake
-
-AC_PREREQ(2.64)
-AC_INIT(GCC-Rust-runtime, 0.1, http://gcc.gnu.org, libgrust,
- https://github.com/redbrain/gccrs)
-AC_CONFIG_SRCDIR(Makefile.am)
-AC_CONFIG_HEADER(config.h)
-
-libtool_VERSION=1:0:0
-AC_SUBST(libtool_VERSION)
-
-AC_CANONICAL_SYSTEM
-target_alias=${target_alias-$host_alias}
-
-
-AM_INIT_AUTOMAKE([1.9.3 no-define foreign no-dist -Wall -Wno-portability])
-AH_TEMPLATE(PACKAGE, [GCC Rust Runtime])
-AH_TEMPLATE(VERSION, [0.1])
-
-m4_rename([_AC_ARG_VAR_PRECIOUS],[glibgrust_PRECIOUS])
-m4_define([_AC_ARG_VAR_PRECIOUS],[])
-AC_PROG_CC
-m4_rename_force([glibgrust_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
-
-AC_SUBST(CFLAGS)
-
-AM_MAINTAINER_MODE
-
-AC_PROG_LD
-AC_CHECK_TOOL(OBJCOPY, objcopy, missing-objcopy)
-
-AC_LIBTOOL_DLOPEN
-AM_PROG_LIBTOOL
-AC_SUBST(enable_shared)
-AC_SUBST(enable_static)
-
-CC_FOR_BUILD=${CC_FOR_BUILD:-gcc}
-AC_SUBST(CC_FOR_BUILD)
-
-AC_PROG_AWK
-
-WARN_FLAGS='-Wall -Wextra -Wwrite-strings -Wcast-qual'
-AC_SUBST(WARN_FLAGS)
-
-dnl FIXME: This should be controlled by --enable-maintainer-mode.
-WERROR="-Werror"
-AC_SUBST(WERROR)
-
-# See if the user wants to configure without libffi. Some
-# architectures don't support it. FIXME: We should set a default
-# based on the host.
-AC_ARG_WITH(libffi,
- AS_HELP_STRING([--without-libffi],
- [don't use libffi]),
- [:],
- [with_libffi=${with_libffi_default-yes}])
-
-LIBFFI=
-LIBFFIINCS=
-if test "$with_libffi" != no; then
- AC_DEFINE(USE_LIBFFI, 1, [Define if we're to use libffi.])
- LIBFFI=../libffi/libffi_convenience.la
- LIBFFIINCS='-I$(top_srcdir)/../libffi/include -I../libffi/include'
-fi
-AC_SUBST(LIBFFI)
-AC_SUBST(LIBFFIINCS)
-
-dnl Test for the -lm library.
-MATH_LIBS=
-AC_CHECK_LIB([m], [sqrt], MATH_LIBS=-lm)
-AC_SUBST(MATH_LIBS)
-
-dnl Test whether the compiler supports the -pthread option.
-AC_CACHE_CHECK([whether -pthread is supported],
-[libgpython_cv_lib_pthread],
-[CFLAGS_hold=$CFLAGS
-CFLAGS="$CFLAGS -pthread"
-AC_COMPILE_IFELSE([[int i;]],
-[libgpython_cv_lib_pthread=yes],
-[libgpython_cv_lib_pthread=no])
-CFLAGS=$CFLAGS_hold])
-PTHREAD_CFLAGS=
-if test "$libgpython_cv_lib_pthread" = yes; then
- PTHREAD_CFLAGS=-pthread
-fi
-AC_SUBST(PTHREAD_CFLAGS)
-
-dnl Test for the -lpthread library.
-PTHREAD_LIBS=
-AC_CHECK_LIB([pthread], [pthread_create], PTHREAD_LIBS=-lpthread)
-AC_SUBST(PTHREAD_LIBS)
-
-AC_C_BIGENDIAN
-
-GCC_CHECK_UNWIND_GETIPINFO
-
-AC_SUBST(CFLAGS)
-AC_SUBST(LDFLAGS)
-
-# Checks for header files.
-AC_HEADER_STDBOOL
-AC_HEADER_STDC
-AC_CHECK_HEADERS([stdlib.h string.h stdarg.h unistd.h \
- stdint.h stdio.h getopt.h \
- assert.h sys/types.h signal.h \
- fcntl.h pthread.h sys/wait.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_CHECK_FUNCS([popen fopen fclose sprintf fprintf strdup \
- strlen strcpy strcmp getopt_long \
- memcpy calloc system sysconf atoi \
- getpid execl fork wait exit atof \
- vfprintf memcmp getc fgets pipe \
- waitpid fdopen])
-
-# Checks for library functions.
-AC_FUNC_MALLOC
-AC_FUNC_UTIME_NULL
-AC_FUNC_VPRINTF
-
-AC_CONFIG_FILES(Makefile)
-AC_OUTPUT
+++ /dev/null
-/* This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#ifndef __GCC_RUST_LANG_HOOKS_H__
-#define __GCC_RUST_LANG_HOOKS_H__
-
-#define LANG_HOOK(name) __GRUST_##name
-
-extern void LANG_HOOK(println) (const char *);
-
-#endif //__GCC_RUST_LANG_HOOKS_H__
+++ /dev/null
-/* This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#ifndef __GCC_RUST_H__
-#define __GCC_RUST_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include <rust/lang-hooks.h>
-
-#endif //__GCC_RUST_H__
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This module implements the `Any` trait, which enables dynamic typing
-//! of any type.
-
-use cast::transmute;
-use cmp::Eq;
-use option::{Option, Some, None};
-use to_bytes::{IterBytes, Cb};
-use to_str::ToStr;
-use unstable::intrinsics;
-use util::Void;
-
-///////////////////////////////////////////////////////////////////////////////
-// TypeId
-///////////////////////////////////////////////////////////////////////////////
-
-/// `TypeId` represents a globally unique identifier for a type
-pub struct TypeId {
- priv t: u64,
-}
-
-impl TypeId {
- /// Returns the `TypeId` of the type this generic function has been instantiated with
- #[inline]
- pub fn of<T: 'static>() -> TypeId {
- TypeId{ t: unsafe { intrinsics::type_id::<T>() } }
- }
-}
-
-impl Eq for TypeId {
- #[inline]
- fn eq(&self, &other: &TypeId) -> bool {
- self.t == other.t
- }
-}
-
-impl IterBytes for TypeId {
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.t.iter_bytes(lsb0, f)
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Any trait
-///////////////////////////////////////////////////////////////////////////////
-
-/// The `Any` trait is implemented by all types, and can be used as a trait object
-/// for dynamic typing
-pub trait Any {
- /// Get the `TypeId` of `self`
- fn get_type_id(&self) -> TypeId;
-
- /// Get a void pointer to `self`
- fn as_void_ptr(&self) -> *Void;
-
- /// Get a mutable void pointer to `self`
- fn as_mut_void_ptr(&mut self) -> *mut Void;
-}
-
-impl<T: 'static> Any for T {
- /// Get the `TypeId` of `self`
- fn get_type_id(&self) -> TypeId {
- TypeId::of::<T>()
- }
-
- /// Get a void pointer to `self`
- fn as_void_ptr(&self) -> *Void {
- self as *T as *Void
- }
-
- /// Get a mutable void pointer to `self`
- fn as_mut_void_ptr(&mut self) -> *mut Void {
- self as *mut T as *mut Void
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Extension methods for Any trait objects.
-// Implemented as three extension traits so that generics work.
-///////////////////////////////////////////////////////////////////////////////
-
-/// Extension methods for a referenced `Any` trait object
-pub trait AnyRefExt<'self> {
- /// Returns true if the boxed type is the same as `T`
- fn is<T: 'static>(self) -> bool;
-
- /// Returns some reference to the boxed value if it is of type `T`, or
- /// `None` if it isn't.
- fn as_ref<T: 'static>(self) -> Option<&'self T>;
-}
-
-impl<'self> AnyRefExt<'self> for &'self Any {
- #[inline]
- fn is<T: 'static>(self) -> bool {
- // Get TypeId of the type this function is instantiated with
- let t = TypeId::of::<T>();
-
- // Get TypeId of the type in the trait object
- let boxed = self.get_type_id();
-
- // Compare both TypeIds on equality
- t == boxed
- }
-
- #[inline]
- fn as_ref<T: 'static>(self) -> Option<&'self T> {
- if self.is::<T>() {
- Some(unsafe { transmute(self.as_void_ptr()) })
- } else {
- None
- }
- }
-}
-
-/// Extension methods for a mutable referenced `Any` trait object
-pub trait AnyMutRefExt<'self> {
- /// Returns some mutable reference to the boxed value if it is of type `T`, or
- /// `None` if it isn't.
- fn as_mut<T: 'static>(self) -> Option<&'self mut T>;
-}
-
-impl<'self> AnyMutRefExt<'self> for &'self mut Any {
- #[inline]
- fn as_mut<T: 'static>(self) -> Option<&'self mut T> {
- if self.is::<T>() {
- Some(unsafe { transmute(self.as_mut_void_ptr()) })
- } else {
- None
- }
- }
-}
-
-/// Extension methods for a owning `Any` trait object
-pub trait AnyOwnExt {
- /// Returns the boxed value if it is of type `T`, or
- /// `None` if it isn't.
- fn move<T: 'static>(self) -> Option<~T>;
-}
-
-impl AnyOwnExt for ~Any {
- #[inline]
- fn move<T: 'static>(self) -> Option<~T> {
- if self.is::<T>() {
- unsafe {
- // Extract the pointer to the boxed value, temporary alias with self
- let ptr: ~T = transmute(self.as_void_ptr());
-
- // Prevent destructor on self being run
- intrinsics::forget(self);
-
- Some(ptr)
- }
- } else {
- None
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Trait implementations
-///////////////////////////////////////////////////////////////////////////////
-
-impl ToStr for ~Any {
- fn to_str(&self) -> ~str { ~"~Any" }
-}
-
-impl<'self> ToStr for &'self Any {
- fn to_str(&self) -> ~str { ~"&Any" }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use super::AnyRefExt;
- use option::{Some, None};
- use hash::Hash;
-
- #[deriving(Eq)]
- struct Test;
-
- static TEST: &'static str = "Test";
-
- #[test]
- fn type_id() {
- let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
- TypeId::of::<Test>());
- let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
- TypeId::of::<Test>());
-
- assert!(a != b);
- assert!(a != c);
- assert!(b != c);
-
- assert_eq!(a, d);
- assert_eq!(b, e);
- assert_eq!(c, f);
- }
-
- #[test]
- fn type_id_hash() {
- let (a, b) = (TypeId::of::<uint>(), TypeId::of::<uint>());
-
- assert_eq!(a.hash(), b.hash());
- }
-
- #[test]
- fn any_as_void_ptr() {
- let (a, b, c) = (~5u as ~Any, ~TEST as ~Any, ~Test as ~Any);
- let a_r: &Any = a;
- let b_r: &Any = b;
- let c_r: &Any = c;
-
- assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
- assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
- assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
- let (a, b, c) = (@5u as @Any, @TEST as @Any, @Test as @Any);
- let a_r: &Any = a;
- let b_r: &Any = b;
- let c_r: &Any = c;
-
- assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
- assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
- assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
- let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any);
- let a_r: &Any = a;
- let b_r: &Any = b;
- let c_r: &Any = c;
-
- assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
- assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
- assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
- let mut x = Test;
- let mut y: &'static str = "Test";
- let (a, b, c) = (&mut 5u as &mut Any,
- &mut y as &mut Any,
- &mut x as &mut Any);
- let a_r: &Any = a;
- let b_r: &Any = b;
- let c_r: &Any = c;
-
- assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
- assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
- assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
- let (a, b, c) = (5u, "hello", Test);
- let (a_r, b_r, c_r) = (&a as &Any, &b as &Any, &c as &Any);
-
- assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
- assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
- assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
- }
-
- #[test]
- fn any_as_mut_void_ptr() {
- let y: &'static str = "Test";
- let mut a = ~5u as ~Any;
- let mut b = ~y as ~Any;
- let mut c = ~Test as ~Any;
-
- let a_ptr = a.as_mut_void_ptr();
- let b_ptr = b.as_mut_void_ptr();
- let c_ptr = c.as_mut_void_ptr();
-
- let a_r: &mut Any = a;
- let b_r: &mut Any = b;
- let c_r: &mut Any = c;
-
- assert_eq!(a_ptr, a_r.as_mut_void_ptr());
- assert_eq!(b_ptr, b_r.as_mut_void_ptr());
- assert_eq!(c_ptr, c_r.as_mut_void_ptr());
-
- let mut x = Test;
- let mut y: &'static str = "Test";
- let a = &mut 5u as &mut Any;
- let b = &mut y as &mut Any;
- let c = &mut x as &mut Any;
-
- let a_ptr = a.as_mut_void_ptr();
- let b_ptr = b.as_mut_void_ptr();
- let c_ptr = c.as_mut_void_ptr();
-
- let a_r: &mut Any = a;
- let b_r: &mut Any = b;
- let c_r: &mut Any = c;
-
- assert_eq!(a_ptr, a_r.as_mut_void_ptr());
- assert_eq!(b_ptr, b_r.as_mut_void_ptr());
- assert_eq!(c_ptr, c_r.as_mut_void_ptr());
-
- let y: &'static str = "Test";
- let mut a = 5u;
- let mut b = y;
- let mut c = Test;
-
- let a_ptr = a.as_mut_void_ptr();
- let b_ptr = b.as_mut_void_ptr();
- let c_ptr = c.as_mut_void_ptr();
-
- let (a_r, b_r, c_r) = (&mut a as &mut Any, &mut b as &mut Any, &mut c as &mut Any);
-
- assert_eq!(a_ptr, a_r.as_mut_void_ptr());
- assert_eq!(b_ptr, b_r.as_mut_void_ptr());
- assert_eq!(c_ptr, c_r.as_mut_void_ptr());
- }
-
- #[test]
- fn any_referenced() {
- let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any);
-
- assert!(a.is::<uint>());
- assert!(!b.is::<uint>());
- assert!(!c.is::<uint>());
-
- assert!(!a.is::<&'static str>());
- assert!(b.is::<&'static str>());
- assert!(!c.is::<&'static str>());
-
- assert!(!a.is::<Test>());
- assert!(!b.is::<Test>());
- assert!(c.is::<Test>());
- }
-
- #[test]
- fn any_owning() {
- let (a, b, c) = (~5u as ~Any, ~TEST as ~Any, ~Test as ~Any);
-
- assert!(a.is::<uint>());
- assert!(!b.is::<uint>());
- assert!(!c.is::<uint>());
-
- assert!(!a.is::<&'static str>());
- assert!(b.is::<&'static str>());
- assert!(!c.is::<&'static str>());
-
- assert!(!a.is::<Test>());
- assert!(!b.is::<Test>());
- assert!(c.is::<Test>());
- }
-
- #[test]
- fn any_managed() {
- let (a, b, c) = (@5u as @Any, @TEST as @Any, @Test as @Any);
-
- assert!(a.is::<uint>());
- assert!(!b.is::<uint>());
- assert!(!c.is::<uint>());
-
- assert!(!a.is::<&'static str>());
- assert!(b.is::<&'static str>());
- assert!(!c.is::<&'static str>());
-
- assert!(!a.is::<Test>());
- assert!(!b.is::<Test>());
- assert!(c.is::<Test>());
- }
-
- #[test]
- fn any_as_ref() {
- let a = &5u as &Any;
-
- match a.as_ref::<uint>() {
- Some(&5) => {}
- x => fail!("Unexpected value {:?}", x)
- }
-
- match a.as_ref::<Test>() {
- None => {}
- x => fail!("Unexpected value {:?}", x)
- }
- }
-
- #[test]
- fn any_as_mut() {
- let mut a = 5u;
- let mut b = ~7u;
-
- let a_r = &mut a as &mut Any;
- let tmp: &mut uint = b;
- let b_r = tmp as &mut Any;
-
- match a_r.as_mut::<uint>() {
- Some(x) => {
- assert_eq!(*x, 5u);
- *x = 612;
- }
- x => fail!("Unexpected value {:?}", x)
- }
-
- match b_r.as_mut::<uint>() {
- Some(x) => {
- assert_eq!(*x, 7u);
- *x = 413;
- }
- x => fail!("Unexpected value {:?}", x)
- }
-
- match a_r.as_mut::<Test>() {
- None => (),
- x => fail!("Unexpected value {:?}", x)
- }
-
- match b_r.as_mut::<Test>() {
- None => (),
- x => fail!("Unexpected value {:?}", x)
- }
-
- match a_r.as_mut::<uint>() {
- Some(&612) => {}
- x => fail!("Unexpected value {:?}", x)
- }
-
- match b_r.as_mut::<uint>() {
- Some(&413) => {}
- x => fail!("Unexpected value {:?}", x)
- }
- }
-
- #[test]
- fn any_move() {
- let a = ~8u as ~Any;
- let b = ~Test as ~Any;
-
- assert_eq!(a.move(), Some(~8u));
- assert_eq!(b.move(), Some(~Test));
-
- let a = ~8u as ~Any;
- let b = ~Test as ~Any;
-
- assert_eq!(a.move(), None::<~Test>);
- assert_eq!(b.move(), None::<~uint>);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations on ASCII strings and characters.
-
-use to_str::{ToStr,ToStrConsume};
-use str;
-use str::StrSlice;
-use str::OwnedStr;
-use container::Container;
-use cast;
-use iter::Iterator;
-use vec::{ImmutableVector, MutableVector};
-use to_bytes::IterBytes;
-use option::{Some, None};
-
-/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
-#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
-pub struct Ascii { priv chr: u8 }
-
-impl Ascii {
- /// Converts a ascii character into a `u8`.
- #[inline]
- pub fn to_byte(self) -> u8 {
- self.chr
- }
-
- /// Converts a ascii character into a `char`.
- #[inline]
- pub fn to_char(self) -> char {
- self.chr as char
- }
-
- /// Convert to lowercase.
- #[inline]
- pub fn to_lower(self) -> Ascii {
- Ascii{chr: ASCII_LOWER_MAP[self.chr]}
- }
-
- /// Convert to uppercase.
- #[inline]
- pub fn to_upper(self) -> Ascii {
- Ascii{chr: ASCII_UPPER_MAP[self.chr]}
- }
-
- /// Compares two ascii characters of equality, ignoring case.
- #[inline]
- pub fn eq_ignore_case(self, other: Ascii) -> bool {
- ASCII_LOWER_MAP[self.chr] == ASCII_LOWER_MAP[other.chr]
- }
-
- // the following methods are like ctype, and the implementation is inspired by musl
-
- /// Check if the character is a letter (a-z, A-Z)
- #[inline]
- pub fn is_alpha(&self) -> bool {
- (self.chr >= 0x41 && self.chr <= 0x5A) || (self.chr >= 0x61 && self.chr <= 0x7A)
- }
-
- /// Check if the character is a number (0-9)
- #[inline]
- pub fn is_digit(&self) -> bool {
- self.chr >= 0x30 && self.chr <= 0x39
- }
-
- /// Check if the character is a letter or number
- #[inline]
- pub fn is_alnum(&self) -> bool {
- self.is_alpha() || self.is_digit()
- }
-
- /// Check if the character is a space or horizontal tab
- #[inline]
- pub fn is_blank(&self) -> bool {
- self.chr == ' ' as u8 || self.chr == '\t' as u8
- }
-
- /// Check if the character is a control character
- #[inline]
- pub fn is_control(&self) -> bool {
- self.chr < 0x20 || self.chr == 0x7F
- }
-
- /// Checks if the character is printable (except space)
- #[inline]
- pub fn is_graph(&self) -> bool {
- (self.chr - 0x21) < 0x5E
- }
-
- /// Checks if the character is printable (including space)
- #[inline]
- pub fn is_print(&self) -> bool {
- (self.chr - 0x20) < 0x5F
- }
-
- /// Checks if the character is lowercase
- #[inline]
- pub fn is_lower(&self) -> bool {
- (self.chr - 'a' as u8) < 26
- }
-
- /// Checks if the character is uppercase
- #[inline]
- pub fn is_upper(&self) -> bool {
- (self.chr - 'A' as u8) < 26
- }
-
- /// Checks if the character is punctuation
- #[inline]
- pub fn is_punctuation(&self) -> bool {
- self.is_graph() && !self.is_alnum()
- }
-
- /// Checks if the character is a valid hex digit
- #[inline]
- pub fn is_hex(&self) -> bool {
- self.is_digit() || ((self.chr | 32u8) - 'a' as u8) < 6
- }
-}
-
-impl ToStr for Ascii {
- #[inline]
- fn to_str(&self) -> ~str {
- // self.chr is always a valid utf8 byte, no need for the check
- unsafe { str::raw::from_byte(self.chr) }
- }
-}
-
-/// Trait for converting into an ascii type.
-pub trait AsciiCast<T> {
- /// Convert to an ascii type
- fn to_ascii(&self) -> T;
-
- /// Convert to an ascii type, not doing any range asserts
- unsafe fn to_ascii_nocheck(&self) -> T;
-
- /// Check if convertible to ascii
- fn is_ascii(&self) -> bool;
-}
-
-impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] {
- #[inline]
- fn to_ascii(&self) -> &'self[Ascii] {
- assert!(self.is_ascii());
- unsafe {self.to_ascii_nocheck()}
- }
-
- #[inline]
- unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] {
- cast::transmute(*self)
- }
-
- #[inline]
- fn is_ascii(&self) -> bool {
- for b in self.iter() {
- if !b.is_ascii() { return false; }
- }
- true
- }
-}
-
-impl<'self> AsciiCast<&'self [Ascii]> for &'self str {
- #[inline]
- fn to_ascii(&self) -> &'self [Ascii] {
- assert!(self.is_ascii());
- unsafe { self.to_ascii_nocheck() }
- }
-
- #[inline]
- unsafe fn to_ascii_nocheck(&self) -> &'self [Ascii] {
- cast::transmute(*self)
- }
-
- #[inline]
- fn is_ascii(&self) -> bool {
- self.bytes().all(|b| b.is_ascii())
- }
-}
-
-impl AsciiCast<Ascii> for u8 {
- #[inline]
- fn to_ascii(&self) -> Ascii {
- assert!(self.is_ascii());
- unsafe {self.to_ascii_nocheck()}
- }
-
- #[inline]
- unsafe fn to_ascii_nocheck(&self) -> Ascii {
- Ascii{ chr: *self }
- }
-
- #[inline]
- fn is_ascii(&self) -> bool {
- *self & 128 == 0u8
- }
-}
-
-impl AsciiCast<Ascii> for char {
- #[inline]
- fn to_ascii(&self) -> Ascii {
- assert!(self.is_ascii());
- unsafe {self.to_ascii_nocheck()}
- }
-
- #[inline]
- unsafe fn to_ascii_nocheck(&self) -> Ascii {
- Ascii{ chr: *self as u8 }
- }
-
- #[inline]
- fn is_ascii(&self) -> bool {
- *self as u32 - ('\x7F' as u32 & *self as u32) == 0
- }
-}
-
-/// Trait for copyless casting to an ascii vector.
-pub trait OwnedAsciiCast {
- /// Take ownership and cast to an ascii vector.
- fn into_ascii(self) -> ~[Ascii];
-
- /// Take ownership and cast to an ascii vector.
- /// Does not perform validation checks.
- unsafe fn into_ascii_nocheck(self) -> ~[Ascii];
-}
-
-impl OwnedAsciiCast for ~[u8] {
- #[inline]
- fn into_ascii(self) -> ~[Ascii] {
- assert!(self.is_ascii());
- unsafe {self.into_ascii_nocheck()}
- }
-
- #[inline]
- unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
- cast::transmute(self)
- }
-}
-
-impl OwnedAsciiCast for ~str {
- #[inline]
- fn into_ascii(self) -> ~[Ascii] {
- assert!(self.is_ascii());
- unsafe {self.into_ascii_nocheck()}
- }
-
- #[inline]
- unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
- cast::transmute(self)
- }
-}
-
-/// Trait for converting an ascii type to a string. Needed to convert
-/// `&[Ascii]` to `&str`.
-pub trait AsciiStr {
- /// Convert to a string.
- fn as_str_ascii<'a>(&'a self) -> &'a str;
-
- /// Convert to vector representing a lower cased ascii string.
- fn to_lower(&self) -> ~[Ascii];
-
- /// Convert to vector representing a upper cased ascii string.
- fn to_upper(&self) -> ~[Ascii];
-
- /// Compares two Ascii strings ignoring case.
- fn eq_ignore_case(self, other: &[Ascii]) -> bool;
-}
-
-impl<'self> AsciiStr for &'self [Ascii] {
- #[inline]
- fn as_str_ascii<'a>(&'a self) -> &'a str {
- unsafe { cast::transmute(*self) }
- }
-
- #[inline]
- fn to_lower(&self) -> ~[Ascii] {
- self.map(|a| a.to_lower())
- }
-
- #[inline]
- fn to_upper(&self) -> ~[Ascii] {
- self.map(|a| a.to_upper())
- }
-
- #[inline]
- fn eq_ignore_case(self, other: &[Ascii]) -> bool {
- self.iter().zip(other.iter()).all(|(&a, &b)| a.eq_ignore_case(b))
- }
-}
-
-impl ToStrConsume for ~[Ascii] {
- #[inline]
- fn into_str(self) -> ~str {
- unsafe { cast::transmute(self) }
- }
-}
-
-impl IterBytes for Ascii {
- #[inline]
- fn iter_bytes(&self, _lsb0: bool, f: |buf: &[u8]| -> bool) -> bool {
- f([self.to_byte()])
- }
-}
-
-/// Trait to convert to a owned byte array by consuming self
-pub trait ToBytesConsume {
- /// Converts to a owned byte array by consuming self
- fn into_bytes(self) -> ~[u8];
-}
-
-impl ToBytesConsume for ~[Ascii] {
- fn into_bytes(self) -> ~[u8] {
- unsafe { cast::transmute(self) }
- }
-}
-
-/// Extension methods for ASCII-subset only operations on owned strings
-pub trait OwnedStrAsciiExt {
- /// Convert the string to ASCII upper case:
- /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
- /// but non-ASCII letters are unchanged.
- fn into_ascii_upper(self) -> ~str;
-
- /// Convert the string to ASCII lower case:
- /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
- /// but non-ASCII letters are unchanged.
- fn into_ascii_lower(self) -> ~str;
-}
-
-/// Extension methods for ASCII-subset only operations on string slices
-pub trait StrAsciiExt {
- /// Makes a copy of the string in ASCII upper case:
- /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
- /// but non-ASCII letters are unchanged.
- fn to_ascii_upper(&self) -> ~str;
-
- /// Makes a copy of the string in ASCII lower case:
- /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
- /// but non-ASCII letters are unchanged.
- fn to_ascii_lower(&self) -> ~str;
-
- /// Check that two strings are an ASCII case-insensitive match.
- /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
- /// but without allocating and copying temporary strings.
- fn eq_ignore_ascii_case(&self, other: &str) -> bool;
-}
-
-impl<'self> StrAsciiExt for &'self str {
- #[inline]
- fn to_ascii_upper(&self) -> ~str {
- unsafe { str_copy_map_bytes(*self, ASCII_UPPER_MAP) }
- }
-
- #[inline]
- fn to_ascii_lower(&self) -> ~str {
- unsafe { str_copy_map_bytes(*self, ASCII_LOWER_MAP) }
- }
-
- #[inline]
- fn eq_ignore_ascii_case(&self, other: &str) -> bool {
- self.len() == other.len() && self.as_bytes().iter().zip(other.as_bytes().iter()).all(
- |(byte_self, byte_other)| ASCII_LOWER_MAP[*byte_self] == ASCII_LOWER_MAP[*byte_other])
- }
-}
-
-impl OwnedStrAsciiExt for ~str {
- #[inline]
- fn into_ascii_upper(self) -> ~str {
- unsafe { str_map_bytes(self, ASCII_UPPER_MAP) }
- }
-
- #[inline]
- fn into_ascii_lower(self) -> ~str {
- unsafe { str_map_bytes(self, ASCII_LOWER_MAP) }
- }
-}
-
-#[inline]
-unsafe fn str_map_bytes(string: ~str, map: &'static [u8]) -> ~str {
- let mut bytes = string.into_bytes();
-
- for b in bytes.mut_iter() {
- *b = map[*b];
- }
-
- str::raw::from_utf8_owned(bytes)
-}
-
-#[inline]
-unsafe fn str_copy_map_bytes(string: &str, map: &'static [u8]) -> ~str {
- let bytes = string.bytes().map(|b| map[b]).to_owned_vec();
-
- str::raw::from_utf8_owned(bytes)
-}
-
-static ASCII_LOWER_MAP: &'static [u8] = &[
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-];
-
-static ASCII_UPPER_MAP: &'static [u8] = &[
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-];
-
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use str::from_char;
- use char::from_u32;
-
- macro_rules! v2ascii (
- ( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
- (~[$($e:expr),*]) => (~[$(Ascii{chr:$e}),*]);
- )
-
- #[test]
- fn test_ascii() {
- assert_eq!(65u8.to_ascii().to_byte(), 65u8);
- assert_eq!(65u8.to_ascii().to_char(), 'A');
- assert_eq!('A'.to_ascii().to_char(), 'A');
- assert_eq!('A'.to_ascii().to_byte(), 65u8);
-
- assert_eq!('A'.to_ascii().to_lower().to_char(), 'a');
- assert_eq!('Z'.to_ascii().to_lower().to_char(), 'z');
- assert_eq!('a'.to_ascii().to_upper().to_char(), 'A');
- assert_eq!('z'.to_ascii().to_upper().to_char(), 'Z');
-
- assert_eq!('@'.to_ascii().to_lower().to_char(), '@');
- assert_eq!('['.to_ascii().to_lower().to_char(), '[');
- assert_eq!('`'.to_ascii().to_upper().to_char(), '`');
- assert_eq!('{'.to_ascii().to_upper().to_char(), '{');
-
- assert!('0'.to_ascii().is_digit());
- assert!('9'.to_ascii().is_digit());
- assert!(!'/'.to_ascii().is_digit());
- assert!(!':'.to_ascii().is_digit());
-
- assert!((0x1fu8).to_ascii().is_control());
- assert!(!' '.to_ascii().is_control());
- assert!((0x7fu8).to_ascii().is_control());
-
- assert!("banana".chars().all(|c| c.is_ascii()));
- assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii()));
- }
-
- #[test]
- fn test_ascii_vec() {
- assert_eq!((&[40u8, 32u8, 59u8]).to_ascii(), v2ascii!([40, 32, 59]));
- assert_eq!("( ;".to_ascii(), v2ascii!([40, 32, 59]));
- // FIXME: #5475 borrowchk error, owned vectors do not live long enough
- // if chained-from directly
- let v = ~[40u8, 32u8, 59u8]; assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));
- let v = ~"( ;"; assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));
-
- assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), ~"abcdef&?#");
- assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), ~"ABCDEF&?#");
-
- assert_eq!("".to_ascii().to_lower().into_str(), ~"");
- assert_eq!("YMCA".to_ascii().to_lower().into_str(), ~"ymca");
- assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), ~"ABCDEFXYZ:.;");
-
- assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
-
- assert!("".is_ascii());
- assert!("a".is_ascii());
- assert!(!"\u2009".is_ascii());
-
- }
-
- #[test]
- fn test_owned_ascii_vec() {
- assert_eq!((~"( ;").into_ascii(), v2ascii!(~[40, 32, 59]));
- assert_eq!((~[40u8, 32u8, 59u8]).into_ascii(), v2ascii!(~[40, 32, 59]));
- }
-
- #[test]
- fn test_ascii_as_str() {
- let v = v2ascii!([40, 32, 59]);
- assert_eq!(v.as_str_ascii(), "( ;");
- }
-
- #[test]
- fn test_ascii_into_str() {
- assert_eq!(v2ascii!(~[40, 32, 59]).into_str(), ~"( ;");
- }
-
- #[test]
- fn test_ascii_to_bytes() {
- assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), ~[40u8, 32u8, 59u8]);
- }
-
- #[test] #[should_fail]
- fn test_ascii_vec_fail_u8_slice() { (&[127u8, 128u8, 255u8]).to_ascii(); }
-
- #[test] #[should_fail]
- fn test_ascii_vec_fail_str_slice() { "zoä华".to_ascii(); }
-
- #[test] #[should_fail]
- fn test_ascii_fail_u8_slice() { 255u8.to_ascii(); }
-
- #[test] #[should_fail]
- fn test_ascii_fail_char_slice() { 'λ'.to_ascii(); }
-
- #[test]
- fn test_to_ascii_upper() {
- assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), ~"URL()URL()URL()üRL");
- assert_eq!("hıKß".to_ascii_upper(), ~"HıKß");
-
- let mut i = 0;
- while i <= 500 {
- let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
- else { i };
- assert_eq!(from_char(from_u32(i).unwrap()).to_ascii_upper(),
- from_char(from_u32(upper).unwrap()))
- i += 1;
- }
- }
-
- #[test]
- fn test_to_ascii_lower() {
- assert_eq!("url()URL()uRl()Ürl".to_ascii_lower(), ~"url()url()url()Ürl");
- // Dotted capital I, Kelvin sign, Sharp S.
- assert_eq!("HİKß".to_ascii_lower(), ~"hİKß");
-
- let mut i = 0;
- while i <= 500 {
- let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
- else { i };
- assert_eq!(from_char(from_u32(i).unwrap()).to_ascii_lower(),
- from_char(from_u32(lower).unwrap()))
- i += 1;
- }
- }
-
- #[test]
- fn test_into_ascii_upper() {
- assert_eq!((~"url()URL()uRl()ürl").into_ascii_upper(), ~"URL()URL()URL()üRL");
- assert_eq!((~"hıKß").into_ascii_upper(), ~"HıKß");
-
- let mut i = 0;
- while i <= 500 {
- let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
- else { i };
- assert_eq!(from_char(from_u32(i).unwrap()).into_ascii_upper(),
- from_char(from_u32(upper).unwrap()))
- i += 1;
- }
- }
-
- #[test]
- fn test_into_ascii_lower() {
- assert_eq!((~"url()URL()uRl()Ürl").into_ascii_lower(), ~"url()url()url()Ürl");
- // Dotted capital I, Kelvin sign, Sharp S.
- assert_eq!((~"HİKß").into_ascii_lower(), ~"hİKß");
-
- let mut i = 0;
- while i <= 500 {
- let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
- else { i };
- assert_eq!(from_char(from_u32(i).unwrap()).into_ascii_lower(),
- from_char(from_u32(lower).unwrap()))
- i += 1;
- }
- }
-
- #[test]
- fn test_eq_ignore_ascii_case() {
- assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl"));
- assert!(!"Ürl".eq_ignore_ascii_case("ürl"));
- // Dotted capital I, Kelvin sign, Sharp S.
- assert!("HİKß".eq_ignore_ascii_case("hİKß"));
- assert!(!"İ".eq_ignore_ascii_case("i"));
- assert!(!"K".eq_ignore_ascii_case("k"));
- assert!(!"ß".eq_ignore_ascii_case("s"));
-
- let mut i = 0;
- while i <= 500 {
- let c = i;
- let lower = if 'A' as u32 <= c && c <= 'Z' as u32 { c + 'a' as u32 - 'A' as u32 }
- else { c };
- assert!(from_char(from_u32(i).unwrap()).
- eq_ignore_ascii_case(from_char(from_u32(lower).unwrap())));
- i += 1;
- }
- }
-
- #[test]
- fn test_to_str() {
- let s = Ascii{ chr: 't' as u8 }.to_str();
- assert_eq!(s, ~"t");
- }
-
-
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Managed vectors
-
-use clone::Clone;
-use container::Container;
-use iter::{Iterator, FromIterator};
-use option::{Option, Some, None};
-use mem;
-use unstable::raw::Repr;
-use vec::{ImmutableVector, OwnedVector};
-
-/// Code for dealing with @-vectors. This is pretty incomplete, and
-/// contains a bunch of duplication from the code for ~-vectors.
-
-/// Returns the number of elements the vector can hold without reallocating
-#[inline]
-pub fn capacity<T>(v: @[T]) -> uint {
- unsafe {
- let box = v.repr();
- (*box).data.alloc / mem::size_of::<T>()
- }
-}
-
-/**
- * Builds a vector by calling a provided function with an argument
- * function that pushes an element to the back of a vector.
- * The initial size for the vector may optionally be specified
- *
- * # Arguments
- *
- * * size - An option, maybe containing initial size of the vector to reserve
- * * builder - A function that will construct the vector. It receives
- * as an argument a function that will push an element
- * onto the vector being constructed.
- */
-#[inline]
-pub fn build<A>(size: Option<uint>, builder: |push: |v: A||) -> @[A] {
- let mut vec = @[];
- unsafe { raw::reserve(&mut vec, size.unwrap_or(4)); }
- builder(|x| unsafe { raw::push(&mut vec, x) });
- vec
-}
-
-// Appending
-
-/// Iterates over the `rhs` vector, copying each element and appending it to the
-/// `lhs`. Afterwards, the `lhs` is then returned for use again.
-#[inline]
-pub fn append<T:Clone>(lhs: @[T], rhs: &[T]) -> @[T] {
- build(Some(lhs.len() + rhs.len()), |push| {
- for x in lhs.iter() {
- push((*x).clone());
- }
- for elt in rhs.iter() {
- push(elt.clone());
- }
- })
-}
-
-
-/// Apply a function to each element of a vector and return the results
-pub fn map<T, U>(v: &[T], f: |x: &T| -> U) -> @[U] {
- build(Some(v.len()), |push| {
- for elem in v.iter() {
- push(f(elem));
- }
- })
-}
-
-/**
- * Creates and initializes an immutable vector.
- *
- * Creates an immutable vector of size `n_elts` and initializes the elements
- * to the value returned by the function `op`.
- */
-pub fn from_fn<T>(n_elts: uint, op: |uint| -> T) -> @[T] {
- build(Some(n_elts), |push| {
- let mut i: uint = 0u;
- while i < n_elts { push(op(i)); i += 1u; }
- })
-}
-
-/**
- * Creates and initializes an immutable vector.
- *
- * Creates an immutable vector of size `n_elts` and initializes the elements
- * to the value `t`.
- */
-pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> @[T] {
- build(Some(n_elts), |push| {
- let mut i: uint = 0u;
- while i < n_elts {
- push(t.clone());
- i += 1u;
- }
- })
-}
-
-/**
- * Creates and initializes an immutable managed vector by moving all the
- * elements from an owned vector.
- */
-pub fn to_managed_move<T>(v: ~[T]) -> @[T] {
- let mut av = @[];
- unsafe {
- raw::reserve(&mut av, v.len());
- for x in v.move_iter() {
- raw::push(&mut av, x);
- }
- av
- }
-}
-
-/**
- * Creates and initializes an immutable managed vector by copying all the
- * elements of a slice.
- */
-pub fn to_managed<T:Clone>(v: &[T]) -> @[T] {
- from_fn(v.len(), |i| v[i].clone())
-}
-
-impl<T> Clone for @[T] {
- fn clone(&self) -> @[T] {
- *self
- }
-}
-
-impl<A> FromIterator<A> for @[A] {
- fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> @[A] {
- let (lower, _) = iterator.size_hint();
- build(Some(lower), |push| {
- for x in *iterator {
- push(x);
- }
- })
- }
-}
-
-#[cfg(not(test))]
-#[allow(missing_doc)]
-pub mod traits {
- use at_vec::append;
- use clone::Clone;
- use ops::Add;
- use vec::Vector;
-
- impl<'self,T:Clone, V: Vector<T>> Add<V,@[T]> for @[T] {
- #[inline]
- fn add(&self, rhs: &V) -> @[T] {
- append(*self, rhs.as_slice())
- }
- }
-}
-
-#[cfg(test)]
-pub mod traits {}
-
-#[allow(missing_doc)]
-pub mod raw {
- use at_vec::capacity;
- use cast;
- use cast::{transmute, transmute_copy};
- use ptr;
- use mem;
- use uint;
- use unstable::intrinsics::{move_val_init, TyDesc};
- use unstable::intrinsics;
- use unstable::raw::{Box, Vec};
-
- /**
- * Sets the length of a vector
- *
- * This will explicitly set the size of the vector, without actually
- * modifying its buffers, so it is up to the caller to ensure that
- * the vector is actually the specified size.
- */
- #[inline]
- pub unsafe fn set_len<T>(v: &mut @[T], new_len: uint) {
- let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
- (*repr).data.fill = new_len * mem::size_of::<T>();
- }
-
- /**
- * Pushes a new value onto this vector.
- */
- #[inline]
- pub unsafe fn push<T>(v: &mut @[T], initval: T) {
- let full = {
- let repr: *Box<Vec<T>> = cast::transmute_copy(v);
- (*repr).data.alloc > (*repr).data.fill
- };
- if full {
- push_fast(v, initval);
- } else {
- push_slow(v, initval);
- }
- }
-
- #[inline] // really pretty please
- unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
- let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
- let amt = v.len();
- (*repr).data.fill += mem::size_of::<T>();
- let p = ptr::offset(&(*repr).data.data as *T, amt as int) as *mut T;
- move_val_init(&mut(*p), initval);
- }
-
- unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
- reserve_at_least(v, v.len() + 1u);
- push_fast(v, initval);
- }
-
- /**
- * Reserves capacity for exactly `n` elements in the given vector.
- *
- * If the capacity for `v` is already equal to or greater than the
- * requested capacity, then no action is taken.
- *
- * # Arguments
- *
- * * v - A vector
- * * n - The number of elements to reserve space for
- */
- pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
- // Only make the (slow) call into the runtime if we have to
- if capacity(*v) < n {
- let ptr: *mut *mut Box<Vec<()>> = transmute(v);
- let ty = intrinsics::get_tydesc::<T>();
- return reserve_raw(ty, ptr, n);
- }
- }
-
- // Implementation detail. Shouldn't be public
- #[allow(missing_doc)]
- pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut Box<Vec<()>>, n: uint) {
- // check for `uint` overflow
- unsafe {
- if n > (**ptr).data.alloc / (*ty).size {
- let alloc = n * (*ty).size;
- let total_size = alloc + mem::size_of::<Vec<()>>();
- if alloc / (*ty).size != n || total_size < alloc {
- fail!("vector size is too large: {}", n);
- }
- (*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box<Vec<()>>;
- (**ptr).data.alloc = alloc;
- }
- }
-
- fn local_realloc(ptr: *(), size: uint) -> *() {
- use rt::local::Local;
- use rt::task::Task;
-
- Local::borrow(|task: &mut Task| {
- task.heap.realloc(ptr as *mut Box<()>, size) as *()
- })
- }
- }
-
- /**
- * Reserves capacity for at least `n` elements in the given vector.
- *
- * This function will over-allocate in order to amortize the
- * allocation costs in scenarios where the caller may need to
- * repeatedly reserve additional space.
- *
- * If the capacity for `v` is already equal to or greater than the
- * requested capacity, then no action is taken.
- *
- * # Arguments
- *
- * * v - A vector
- * * n - The number of elements to reserve space for
- */
- pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
- reserve(v, uint::next_power_of_two(n));
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use prelude::*;
- use bh = extra::test::BenchHarness;
-
- #[test]
- fn test() {
- // Some code that could use that, then:
- fn seq_range(lo: uint, hi: uint) -> @[uint] {
- build(None, |push| {
- for i in range(lo, hi) {
- push(i);
- }
- })
- }
-
- assert_eq!(seq_range(10, 15), @[10, 11, 12, 13, 14]);
- assert_eq!(from_fn(5, |x| x+1), @[1, 2, 3, 4, 5]);
- assert_eq!(from_elem(5, 3.14), @[3.14, 3.14, 3.14, 3.14, 3.14]);
- }
-
- #[test]
- fn append_test() {
- assert_eq!(@[1,2,3] + &[4,5,6], @[1,2,3,4,5,6]);
- }
-
- #[test]
- fn test_to_managed_move() {
- assert_eq!(to_managed_move::<int>(~[]), @[]);
- assert_eq!(to_managed_move(~[true]), @[true]);
- assert_eq!(to_managed_move(~[1, 2, 3, 4, 5]), @[1, 2, 3, 4, 5]);
- assert_eq!(to_managed_move(~[~"abc", ~"123"]), @[~"abc", ~"123"]);
- assert_eq!(to_managed_move(~[~[42]]), @[~[42]]);
- }
-
- #[test]
- fn test_to_managed() {
- assert_eq!(to_managed::<int>([]), @[]);
- assert_eq!(to_managed([true]), @[true]);
- assert_eq!(to_managed([1, 2, 3, 4, 5]), @[1, 2, 3, 4, 5]);
- assert_eq!(to_managed([@"abc", @"123"]), @[@"abc", @"123"]);
- assert_eq!(to_managed([@[42]]), @[@[42]]);
- }
-
- #[bench]
- fn bench_capacity(b: &mut bh) {
- let x = @[1, 2, 3];
- b.iter(|| {
- let _ = capacity(x);
- });
- }
-
- #[bench]
- fn bench_build_sized(b: &mut bh) {
- let len = 64;
- b.iter(|| {
- build(Some(len), |push| for i in range(0, 1024) { push(i) });
- });
- }
-
- #[bench]
- fn bench_build(b: &mut bh) {
- b.iter(|| {
- for i in range(0, 95) {
- build(None, |push| push(i));
- }
- });
- }
-
- #[bench]
- fn bench_append(b: &mut bh) {
- let lhs = @[7, ..128];
- let rhs = range(0, 256).to_owned_vec();
- b.iter(|| {
- let _ = append(lhs, rhs);
- })
- }
-
- #[bench]
- fn bench_map(b: &mut bh) {
- let elts = range(0, 256).to_owned_vec();
- b.iter(|| {
- let _ = map(elts, |x| x*2);
- })
- }
-
- #[bench]
- fn bench_from_fn(b: &mut bh) {
- b.iter(|| {
- let _ = from_fn(1024, |x| x);
- });
- }
-
- #[bench]
- fn bench_from_elem(b: &mut bh) {
- b.iter(|| {
- let _ = from_elem(1024, 0u64);
- });
- }
-
- #[bench]
- fn bench_to_managed_move(b: &mut bh) {
- b.iter(|| {
- let elts = range(0, 1024).to_owned_vec(); // yikes! can't move out of capture, though
- to_managed_move(elts);
- })
- }
-
- #[bench]
- fn bench_to_managed(b: &mut bh) {
- let elts = range(0, 1024).to_owned_vec();
- b.iter(|| {
- let _ = to_managed(elts);
- });
- }
-
- #[bench]
- fn bench_clone(b: &mut bh) {
- let elts = to_managed(range(0, 1024).to_owned_vec());
- b.iter(|| {
- let _ = elts.clone();
- });
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The `bool` module contains useful code to help work with boolean values.
-//!
-//! A quick summary:
-//!
-//! ## Trait implementations for `bool`
-//!
-//! Implementations of the following traits:
-//!
-//! * `FromStr`
-//! * `ToStr`
-//! * `Not`
-//! * `Ord`
-//! * `TotalOrd`
-//! * `Eq`
-//! * `Default`
-//! * `Zero`
-//!
-//! ## Various functions to compare `bool`s
-//!
-//! All of the standard comparison functions one would expect: `and`, `eq`, `or`,
-//! and more.
-//!
-//! Also, a few conversion functions: `to_bit` and `to_str`.
-
-use option::{None, Option, Some};
-use from_str::FromStr;
-use to_str::ToStr;
-use num::FromPrimitive;
-
-#[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering};
-#[cfg(not(test))] use ops::{Not, BitAnd, BitOr, BitXor};
-#[cfg(not(test))] use default::Default;
-#[cfg(not(test))] use num::Zero;
-
-/////////////////////////////////////////////////////////////////////////////
-// Freestanding functions
-/////////////////////////////////////////////////////////////////////////////
-
-/// Iterates over all truth values, passing them to the given block.
-///
-/// There are no guarantees about the order values will be given.
-///
-/// # Examples
-///
-/// ```
-/// std::bool::all_values(|x: bool| {
-/// println(x.to_str());
-/// })
-/// ```
-#[inline]
-pub fn all_values(blk: |v: bool|) {
- blk(true);
- blk(false);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Methods on `bool`
-/////////////////////////////////////////////////////////////////////////////
-
-/// Extension methods on a `bool`
-pub trait Bool {
- /// Conjunction of two boolean values.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(true.and(true), true);
- /// assert_eq!(true.and(false), false);
- /// assert_eq!(false.and(true), false);
- /// assert_eq!(false.and(false), false);
- /// ```
- fn and(self, b: bool) -> bool;
-
- /// Disjunction of two boolean values.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(true.or(true), true);
- /// assert_eq!(true.or(false), true);
- /// assert_eq!(false.or(true), true);
- /// assert_eq!(false.or(false), false);
- /// ```
- fn or(self, b: bool) -> bool;
-
- /// An 'exclusive or' of two boolean values.
- ///
- /// 'exclusive or' is identical to `or(and(a, not(b)), and(not(a), b))`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(true.xor(true), false);
- /// assert_eq!(true.xor(false), true);
- /// assert_eq!(false.xor(true), true);
- /// assert_eq!(false.xor(false), false);
- /// ```
- fn xor(self, b: bool) -> bool;
-
- /// Implication between two boolean values.
- ///
- /// Implication is often phrased as 'if a then b.'
- ///
- /// 'if a then b' is equivalent to `!a || b`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(true.implies(true), true);
- /// assert_eq!(true.implies(false), false);
- /// assert_eq!(false.implies(true), true);
- /// assert_eq!(false.implies(false), true);
- /// ```
- fn implies(self, b: bool) -> bool;
-
- /// Convert a `bool` to a `u8`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(true.to_bit::<u8>(), 1u8);
- /// assert_eq!(false.to_bit::<u8>(), 0u8);
- /// ```
- fn to_bit<N: FromPrimitive>(self) -> N;
-}
-
-impl Bool for bool {
- #[inline]
- fn and(self, b: bool) -> bool { self && b }
-
- #[inline]
- fn or(self, b: bool) -> bool { self || b }
-
- #[inline]
- fn xor(self, b: bool) -> bool { self ^ b }
-
- #[inline]
- fn implies(self, b: bool) -> bool { !self || b }
-
- #[inline]
- fn to_bit<N: FromPrimitive>(self) -> N {
- if self { FromPrimitive::from_u8(1).unwrap() }
- else { FromPrimitive::from_u8(0).unwrap() }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Trait impls on `bool`
-/////////////////////////////////////////////////////////////////////////////
-
-impl FromStr for bool {
- /// Parse a `bool` from a string.
- ///
- /// Yields an `Option<bool>`, because `s` may or may not actually be parseable.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(from_str::<bool>("true"), Some(true));
- /// assert_eq!(from_str::<bool>("false"), Some(false));
- /// assert_eq!(from_str::<bool>("not even a boolean"), None);
- /// ```
- #[inline]
- fn from_str(s: &str) -> Option<bool> {
- match s {
- "true" => Some(true),
- "false" => Some(false),
- _ => None,
- }
- }
-}
-
-impl ToStr for bool {
- /// Convert a `bool` to a string.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(true.to_str(), ~"true");
- /// assert_eq!(false.to_str(), ~"false");
- /// ```
- #[inline]
- fn to_str(&self) -> ~str {
- if *self { ~"true" } else { ~"false" }
- }
-}
-
-#[cfg(not(test))]
-impl Not<bool> for bool {
- /// The logical complement of a boolean value.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(!true, false);
- /// assert_eq!(!false, true);
- /// ```
- #[inline]
- fn not(&self) -> bool { !*self }
-}
-
-#[cfg(not(test))]
-impl BitAnd<bool, bool> for bool {
- /// Conjunction of two boolean values.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(false.bitand(&false), false);
- /// assert_eq!(true.bitand(&false), false);
- /// assert_eq!(false.bitand(&true), false);
- /// assert_eq!(true.bitand(&true), true);
- ///
- /// assert_eq!(false & false, false);
- /// assert_eq!(true & false, false);
- /// assert_eq!(false & true, false);
- /// assert_eq!(true & true, true);
- /// ```
- #[inline]
- fn bitand(&self, b: &bool) -> bool { *self & *b }
-}
-
-#[cfg(not(test))]
-impl BitOr<bool, bool> for bool {
- /// Disjunction of two boolean values.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(false.bitor(&false), false);
- /// assert_eq!(true.bitor(&false), true);
- /// assert_eq!(false.bitor(&true), true);
- /// assert_eq!(true.bitor(&true), true);
- ///
- /// assert_eq!(false | false, false);
- /// assert_eq!(true | false, true);
- /// assert_eq!(false | true, true);
- /// assert_eq!(true | true, true);
- /// ```
- #[inline]
- fn bitor(&self, b: &bool) -> bool { *self | *b }
-}
-
-#[cfg(not(test))]
-impl BitXor<bool, bool> for bool {
- /// An 'exclusive or' of two boolean values.
- ///
- /// 'exclusive or' is identical to `or(and(a, not(b)), and(not(a), b))`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// assert_eq!(false.bitxor(&false), false);
- /// assert_eq!(true.bitxor(&false), true);
- /// assert_eq!(false.bitxor(&true), true);
- /// assert_eq!(true.bitxor(&true), false);
- ///
- /// assert_eq!(false ^ false, false);
- /// assert_eq!(true ^ false, true);
- /// assert_eq!(false ^ true, true);
- /// assert_eq!(true ^ true, false);
- /// ```
- #[inline]
- fn bitxor(&self, b: &bool) -> bool { *self ^ *b }
-}
-
-#[cfg(not(test))]
-impl Ord for bool {
- #[inline]
- fn lt(&self, other: &bool) -> bool { self.to_bit::<u8>() < other.to_bit() }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for bool {
- #[inline]
- fn cmp(&self, other: &bool) -> Ordering { self.to_bit::<u8>().cmp(&other.to_bit()) }
-}
-
-/// Equality between two boolean values.
-///
-/// Two booleans are equal if they have the same value.
-///
-/// # Examples
-///
-/// ```rust
-/// assert_eq!(false.eq(&true), false);
-/// assert_eq!(false == false, true);
-/// assert_eq!(false != true, true);
-/// assert_eq!(false.ne(&false), false);
-/// ```
-#[cfg(not(test))]
-impl Eq for bool {
- #[inline]
- fn eq(&self, other: &bool) -> bool { (*self) == (*other) }
-}
-
-#[cfg(not(test))]
-impl Default for bool {
- fn default() -> bool { false }
-}
-
-#[cfg(not(test))]
-impl Zero for bool {
- fn zero() -> bool { false }
- fn is_zero(&self) -> bool { *self == false }
-}
-
-#[cfg(test)]
-mod tests {
- use cmp::{Equal, Greater, Less, Eq, TotalOrd};
- use ops::{BitAnd, BitXor, BitOr};
- use from_str::{FromStr, from_str};
- use option::{Some, None};
- use super::all_values;
-
- #[test]
- fn test_bool() {
- assert_eq!(false.eq(&true), false);
- assert_eq!(false == false, true);
- assert_eq!(false != true, true);
- assert_eq!(false.ne(&false), false);
-
- assert_eq!(false.bitand(&false), false);
- assert_eq!(true.bitand(&false), false);
- assert_eq!(false.bitand(&true), false);
- assert_eq!(true.bitand(&true), true);
-
- assert_eq!(false & false, false);
- assert_eq!(true & false, false);
- assert_eq!(false & true, false);
- assert_eq!(true & true, true);
-
- assert_eq!(false.bitor(&false), false);
- assert_eq!(true.bitor(&false), true);
- assert_eq!(false.bitor(&true), true);
- assert_eq!(true.bitor(&true), true);
-
- assert_eq!(false | false, false);
- assert_eq!(true | false, true);
- assert_eq!(false | true, true);
- assert_eq!(true | true, true);
-
- assert_eq!(false.bitxor(&false), false);
- assert_eq!(true.bitxor(&false), true);
- assert_eq!(false.bitxor(&true), true);
- assert_eq!(true.bitxor(&true), false);
-
- assert_eq!(false ^ false, false);
- assert_eq!(true ^ false, true);
- assert_eq!(false ^ true, true);
- assert_eq!(true ^ true, false);
-
- assert_eq!(!true, false);
- assert_eq!(!false, true);
-
- assert_eq!(true.to_str(), ~"true");
- assert_eq!(false.to_str(), ~"false");
-
- assert_eq!(from_str::<bool>("true"), Some(true));
- assert_eq!(from_str::<bool>("false"), Some(false));
- assert_eq!(from_str::<bool>("not even a boolean"), None);
-
- assert_eq!(true.and(true), true);
- assert_eq!(true.and(false), false);
- assert_eq!(false.and(true), false);
- assert_eq!(false.and(false), false);
-
- assert_eq!(true.or(true), true);
- assert_eq!(true.or(false), true);
- assert_eq!(false.or(true), true);
- assert_eq!(false.or(false), false);
-
- assert_eq!(true.xor(true), false);
- assert_eq!(true.xor(false), true);
- assert_eq!(false.xor(true), true);
- assert_eq!(false.xor(false), false);
-
- assert_eq!(true.implies(true), true);
- assert_eq!(true.implies(false), false);
- assert_eq!(false.implies(true), true);
- assert_eq!(false.implies(false), true);
-
- assert_eq!(true.to_bit::<u8>(), 1u8);
- assert_eq!(false.to_bit::<u8>(), 0u8);
- }
-
- #[test]
- fn test_bool_from_str() {
- all_values(|v| {
- assert!(Some(v) == FromStr::from_str(v.to_str()))
- });
- }
-
- #[test]
- fn test_bool_to_str() {
- assert_eq!(false.to_str(), ~"false");
- assert_eq!(true.to_str(), ~"true");
- }
-
- #[test]
- fn test_bool_to_bit() {
- all_values(|v| {
- assert_eq!(v.to_bit::<u8>(), if v { 1u8 } else { 0u8 });
- assert_eq!(v.to_bit::<uint>(), if v { 1u } else { 0u });
- assert_eq!(v.to_bit::<int>(), if v { 1i } else { 0i });
- });
- }
-
- #[test]
- fn test_bool_ord() {
- assert!(true > false);
- assert!(!(false > true));
-
- assert!(false < true);
- assert!(!(true < false));
-
- assert!(false <= false);
- assert!(false >= false);
- assert!(true <= true);
- assert!(true >= true);
-
- assert!(false <= true);
- assert!(!(false >= true));
- assert!(true >= false);
- assert!(!(true <= false));
- }
-
- #[test]
- fn test_bool_totalord() {
- assert_eq!(true.cmp(&true), Equal);
- assert_eq!(false.cmp(&false), Equal);
- assert_eq!(true.cmp(&false), Greater);
- assert_eq!(false.cmp(&true), Less);
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Borrowed pointer utilities
-
-#[cfg(not(test))]
-use prelude::*;
-
-/// Cast a region pointer - &T - to a uint.
-#[inline]
-pub fn to_uint<T>(thing: &T) -> uint {
- thing as *T as uint
-}
-
-/// Determine if two borrowed pointers point to the same thing.
-#[inline]
-pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool {
- (thing as *T) == (other as *T)
-}
-
-// Equality for region pointers
-#[cfg(not(test))]
-impl<'self, T: Eq> Eq for &'self T {
- #[inline]
- fn eq(&self, other: & &'self T) -> bool {
- *(*self) == *(*other)
- }
- #[inline]
- fn ne(&self, other: & &'self T) -> bool {
- *(*self) != *(*other)
- }
-}
-
-// Comparison for region pointers
-#[cfg(not(test))]
-impl<'self, T: Ord> Ord for &'self T {
- #[inline]
- fn lt(&self, other: & &'self T) -> bool {
- *(*self) < *(*other)
- }
- #[inline]
- fn le(&self, other: & &'self T) -> bool {
- *(*self) <= *(*other)
- }
- #[inline]
- fn ge(&self, other: & &'self T) -> bool {
- *(*self) >= *(*other)
- }
- #[inline]
- fn gt(&self, other: & &'self T) -> bool {
- *(*self) > *(*other)
- }
-}
-
-#[cfg(not(test))]
-impl<'self, T: TotalOrd> TotalOrd for &'self T {
- #[inline]
- fn cmp(&self, other: & &'self T) -> Ordering { (**self).cmp(*other) }
-}
-
-#[cfg(not(test))]
-impl<'self, T: TotalEq> TotalEq for &'self T {
- #[inline]
- fn equals(&self, other: & &'self T) -> bool { (**self).equals(*other) }
-}
-
-#[cfg(test)]
-mod tests {
- use super::ref_eq;
-
- #[test]
- fn test_ref_eq() {
- let x = 1;
- let y = 1;
-
- assert!(ref_eq(&x, &x));
- assert!(!ref_eq(&x, &y));
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-C-string manipulation and management
-
-This modules provides the basic methods for creating and manipulating
-null-terminated strings for use with FFI calls (back to C). Most C APIs require
-that the string being passed to them is null-terminated, and by default rust's
-string types are *not* null terminated.
-
-The other problem with translating Rust strings to C strings is that Rust
-strings can validly contain a null-byte in the middle of the string (0 is a
-valid unicode codepoint). This means that not all Rust strings can actually be
-translated to C strings.
-
-# Creation of a C string
-
-A C string is managed through the `CString` type defined in this module. It
-"owns" the internal buffer of characters and will automatically deallocate the
-buffer when the string is dropped. The `ToCStr` trait is implemented for `&str`
-and `&[u8]`, but the conversions can fail due to some of the limitations
-explained above.
-
-This also means that currently whenever a C string is created, an allocation
-must be performed to place the data elsewhere (the lifetime of the C string is
-not tied to the lifetime of the original string/data buffer). If C strings are
-heavily used in applications, then caching may be advisable to prevent
-unnecessary amounts of allocations.
-
-An example of creating and using a C string would be:
-
-```rust
-use std::libc;
-extern {
- fn puts(s: *libc::c_char);
-}
-
-let my_string = "Hello, world!";
-
-// Allocate the C string with an explicit local that owns the string. The
-// `c_buffer` pointer will be deallocated when `my_c_string` goes out of scope.
-let my_c_string = my_string.to_c_str();
-my_c_string.with_ref(|c_buffer| {
- unsafe { puts(c_buffer); }
-})
-
-// Don't save off the allocation of the C string, the `c_buffer` will be
-// deallocated when this block returns!
-my_string.with_c_str(|c_buffer| {
- unsafe { puts(c_buffer); }
-})
- ```
-
-*/
-
-use cast;
-use container::Container;
-use iter::{Iterator, range};
-use libc;
-use ops::Drop;
-use option::{Option, Some, None};
-use ptr::RawPtr;
-use ptr;
-use str::StrSlice;
-use str;
-use vec::{CopyableVector, ImmutableVector, MutableVector};
-use vec;
-use unstable::intrinsics;
-
-/// Resolution options for the `null_byte` condition
-pub enum NullByteResolution {
- /// Truncate at the null byte
- Truncate,
- /// Use a replacement byte
- ReplaceWith(libc::c_char)
-}
-
-condition! {
- // This should be &[u8] but there's a lifetime issue (#5370).
- pub null_byte: (~[u8]) -> NullByteResolution;
-}
-
-/// The representation of a C String.
-///
-/// This structure wraps a `*libc::c_char`, and will automatically free the
-/// memory it is pointing to when it goes out of scope.
-pub struct CString {
- priv buf: *libc::c_char,
- priv owns_buffer_: bool,
-}
-
-impl CString {
- /// Create a C String from a pointer.
- pub unsafe fn new(buf: *libc::c_char, owns_buffer: bool) -> CString {
- CString { buf: buf, owns_buffer_: owns_buffer }
- }
-
- /// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
- /// Any ownership of the buffer by the `CString` wrapper is forgotten.
- pub unsafe fn unwrap(self) -> *libc::c_char {
- let mut c_str = self;
- c_str.owns_buffer_ = false;
- c_str.buf
- }
-
- /// Calls a closure with a reference to the underlying `*libc::c_char`.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
- pub fn with_ref<T>(&self, f: |*libc::c_char| -> T) -> T {
- if self.buf.is_null() { fail!("CString is null!"); }
- f(self.buf)
- }
-
- /// Calls a closure with a mutable reference to the underlying `*libc::c_char`.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
- pub fn with_mut_ref<T>(&mut self, f: |*mut libc::c_char| -> T) -> T {
- if self.buf.is_null() { fail!("CString is null!"); }
- f(unsafe { cast::transmute_mut_unsafe(self.buf) })
- }
-
- /// Returns true if the CString is a null.
- pub fn is_null(&self) -> bool {
- self.buf.is_null()
- }
-
- /// Returns true if the CString is not null.
- pub fn is_not_null(&self) -> bool {
- self.buf.is_not_null()
- }
-
- /// Returns whether or not the `CString` owns the buffer.
- pub fn owns_buffer(&self) -> bool {
- self.owns_buffer_
- }
-
- /// Converts the CString into a `&[u8]` without copying.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
- #[inline]
- pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
- if self.buf.is_null() { fail!("CString is null!"); }
- unsafe {
- cast::transmute((self.buf, self.len() + 1))
- }
- }
-
- /// Converts the CString into a `&str` without copying.
- /// Returns None if the CString is not UTF-8 or is null.
- #[inline]
- pub fn as_str<'a>(&'a self) -> Option<&'a str> {
- if self.buf.is_null() { return None; }
- let buf = self.as_bytes();
- let buf = buf.slice_to(buf.len()-1); // chop off the trailing NUL
- str::from_utf8_slice_opt(buf)
- }
-
- /// Return a CString iterator.
- pub fn iter<'a>(&'a self) -> CStringIterator<'a> {
- CStringIterator {
- ptr: self.buf,
- lifetime: unsafe { cast::transmute(self.buf) },
- }
- }
-}
-
-impl Drop for CString {
- fn drop(&mut self) {
- if self.owns_buffer_ {
- unsafe {
- libc::free(self.buf as *libc::c_void)
- }
- }
- }
-}
-
-impl Container for CString {
- #[inline]
- fn len(&self) -> uint {
- unsafe {
- ptr::position(self.buf, |c| *c == 0)
- }
- }
-}
-
-/// A generic trait for converting a value to a CString.
-pub trait ToCStr {
- /// Copy the receiver into a CString.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the receiver has an interior null.
- fn to_c_str(&self) -> CString;
-
- /// Unsafe variant of `to_c_str()` that doesn't check for nulls.
- unsafe fn to_c_str_unchecked(&self) -> CString;
-
- /// Work with a temporary CString constructed from the receiver.
- /// The provided `*libc::c_char` will be freed immediately upon return.
- ///
- /// # Example
- ///
- /// ```rust
- /// let s = "PATH".with_c_str(|path| libc::getenv(path))
- /// ```
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the receiver has an interior null.
- #[inline]
- fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
- self.to_c_str().with_ref(f)
- }
-
- /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
- #[inline]
- unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
- self.to_c_str_unchecked().with_ref(f)
- }
-}
-
-impl<'self> ToCStr for &'self str {
- #[inline]
- fn to_c_str(&self) -> CString {
- self.as_bytes().to_c_str()
- }
-
- #[inline]
- unsafe fn to_c_str_unchecked(&self) -> CString {
- self.as_bytes().to_c_str_unchecked()
- }
-
- #[inline]
- fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
- self.as_bytes().with_c_str(f)
- }
-
- #[inline]
- unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
- self.as_bytes().with_c_str_unchecked(f)
- }
-}
-
-// The length of the stack allocated buffer for `vec.with_c_str()`
-static BUF_LEN: uint = 128;
-
-impl<'self> ToCStr for &'self [u8] {
- fn to_c_str(&self) -> CString {
- let mut cs = unsafe { self.to_c_str_unchecked() };
- cs.with_mut_ref(|buf| check_for_null(*self, buf));
- cs
- }
-
- unsafe fn to_c_str_unchecked(&self) -> CString {
- self.as_imm_buf(|self_buf, self_len| {
- let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
- if buf.is_null() {
- fail!("failed to allocate memory!");
- }
-
- ptr::copy_memory(buf, self_buf, self_len);
- *ptr::mut_offset(buf, self_len as int) = 0;
-
- CString::new(buf as *libc::c_char, true)
- })
- }
-
- fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
- unsafe { with_c_str(*self, true, f) }
- }
-
- unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
- with_c_str(*self, false, f)
- }
-}
-
-// Unsafe function that handles possibly copying the &[u8] into a stack array.
-unsafe fn with_c_str<T>(v: &[u8], checked: bool, f: |*libc::c_char| -> T) -> T {
- if v.len() < BUF_LEN {
- let mut buf: [u8, .. BUF_LEN] = intrinsics::uninit();
- vec::bytes::copy_memory(buf, v, v.len());
- buf[v.len()] = 0;
-
- buf.as_mut_buf(|buf, _| {
- if checked {
- check_for_null(v, buf as *mut libc::c_char);
- }
-
- f(buf as *libc::c_char)
- })
- } else if checked {
- v.to_c_str().with_ref(f)
- } else {
- v.to_c_str_unchecked().with_ref(f)
- }
-}
-
-#[inline]
-fn check_for_null(v: &[u8], buf: *mut libc::c_char) {
- for i in range(0, v.len()) {
- unsafe {
- let p = buf.offset(i as int);
- if *p == 0 {
- match null_byte::cond.raise(v.to_owned()) {
- Truncate => break,
- ReplaceWith(c) => *p = c
- }
- }
- }
- }
-}
-
-/// External iterator for a CString's bytes.
-///
-/// Use with the `std::iter` module.
-pub struct CStringIterator<'self> {
- priv ptr: *libc::c_char,
- priv lifetime: &'self libc::c_char, // FIXME: #5922
-}
-
-impl<'self> Iterator<libc::c_char> for CStringIterator<'self> {
- fn next(&mut self) -> Option<libc::c_char> {
- let ch = unsafe { *self.ptr };
- if ch == 0 {
- None
- } else {
- self.ptr = unsafe { ptr::offset(self.ptr, 1) };
- Some(ch)
- }
- }
-}
-
-/// Parses a C "multistring", eg windows env values or
-/// the req->ptr result in a uv_fs_readdir() call.
-///
-/// Optionally, a `count` can be passed in, limiting the
-/// parsing to only being done `count`-times.
-///
-/// The specified closure is invoked with each string that
-/// is found, and the number of strings found is returned.
-pub unsafe fn from_c_multistring(buf: *libc::c_char,
- count: Option<uint>,
- f: |&CString|) -> uint {
-
- let mut curr_ptr: uint = buf as uint;
- let mut ctr = 0;
- let (limited_count, limit) = match count {
- Some(limit) => (true, limit),
- None => (false, 0)
- };
- while ((limited_count && ctr < limit) || !limited_count)
- && *(curr_ptr as *libc::c_char) != 0 as libc::c_char {
- let cstr = CString::new(curr_ptr as *libc::c_char, false);
- f(&cstr);
- curr_ptr += cstr.len() + 1;
- ctr += 1;
- }
- return ctr;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use libc;
- use ptr;
- use option::{Some, None};
- use vec;
-
- #[test]
- fn test_str_multistring_parsing() {
- unsafe {
- let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
- let ptr = vec::raw::to_ptr(input);
- let expected = ["zero", "one"];
- let mut it = expected.iter();
- let result = from_c_multistring(ptr as *libc::c_char, None, |c| {
- let cbytes = c.as_bytes().slice_to(c.len());
- assert_eq!(cbytes, it.next().unwrap().as_bytes());
- });
- assert_eq!(result, 2);
- assert!(it.next().is_none());
- }
- }
-
- #[test]
- fn test_str_to_c_str() {
- "".to_c_str().with_ref(|buf| {
- unsafe {
- assert_eq!(*ptr::offset(buf, 0), 0);
- }
- });
-
- "hello".to_c_str().with_ref(|buf| {
- unsafe {
- assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 5), 0);
- }
- })
- }
-
- #[test]
- fn test_vec_to_c_str() {
- let b: &[u8] = [];
- b.to_c_str().with_ref(|buf| {
- unsafe {
- assert_eq!(*ptr::offset(buf, 0), 0);
- }
- });
-
- let _ = bytes!("hello").to_c_str().with_ref(|buf| {
- unsafe {
- assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 5), 0);
- }
- });
-
- let _ = bytes!("foo", 0xff).to_c_str().with_ref(|buf| {
- unsafe {
- assert_eq!(*ptr::offset(buf, 0), 'f' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 1), 'o' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 2), 'o' as libc::c_char);
- assert_eq!(*ptr::offset(buf, 3), 0xff);
- assert_eq!(*ptr::offset(buf, 4), 0);
- }
- });
- }
-
- #[test]
- fn test_is_null() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- assert!(c_str.is_null());
- assert!(!c_str.is_not_null());
- }
-
- #[test]
- fn test_unwrap() {
- let c_str = "hello".to_c_str();
- unsafe { libc::free(c_str.unwrap() as *libc::c_void) }
- }
-
- #[test]
- fn test_with_ref() {
- let c_str = "hello".to_c_str();
- let len = unsafe { c_str.with_ref(|buf| libc::strlen(buf)) };
- assert!(!c_str.is_null());
- assert!(c_str.is_not_null());
- assert_eq!(len, 5);
- }
-
- #[test]
- #[should_fail]
- fn test_with_ref_empty_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.with_ref(|_| ());
- }
-
- #[test]
- fn test_iterator() {
- let c_str = "".to_c_str();
- let mut iter = c_str.iter();
- assert_eq!(iter.next(), None);
-
- let c_str = "hello".to_c_str();
- let mut iter = c_str.iter();
- assert_eq!(iter.next(), Some('h' as libc::c_char));
- assert_eq!(iter.next(), Some('e' as libc::c_char));
- assert_eq!(iter.next(), Some('l' as libc::c_char));
- assert_eq!(iter.next(), Some('l' as libc::c_char));
- assert_eq!(iter.next(), Some('o' as libc::c_char));
- assert_eq!(iter.next(), None);
- }
-
- #[test]
- fn test_to_c_str_fail() {
- use c_str::null_byte::cond;
-
- let mut error_happened = false;
- cond.trap(|err| {
- assert_eq!(err, bytes!("he", 0, "llo").to_owned())
- error_happened = true;
- Truncate
- }).inside(|| "he\x00llo".to_c_str());
- assert!(error_happened);
-
- cond.trap(|_| {
- ReplaceWith('?' as libc::c_char)
- }).inside(|| "he\x00llo".to_c_str()).with_ref(|buf| {
- unsafe {
- assert_eq!(*buf.offset(0), 'h' as libc::c_char);
- assert_eq!(*buf.offset(1), 'e' as libc::c_char);
- assert_eq!(*buf.offset(2), '?' as libc::c_char);
- assert_eq!(*buf.offset(3), 'l' as libc::c_char);
- assert_eq!(*buf.offset(4), 'l' as libc::c_char);
- assert_eq!(*buf.offset(5), 'o' as libc::c_char);
- assert_eq!(*buf.offset(6), 0);
- }
- })
- }
-
- #[test]
- fn test_to_c_str_unchecked() {
- unsafe {
- "he\x00llo".to_c_str_unchecked().with_ref(|buf| {
- assert_eq!(*buf.offset(0), 'h' as libc::c_char);
- assert_eq!(*buf.offset(1), 'e' as libc::c_char);
- assert_eq!(*buf.offset(2), 0);
- assert_eq!(*buf.offset(3), 'l' as libc::c_char);
- assert_eq!(*buf.offset(4), 'l' as libc::c_char);
- assert_eq!(*buf.offset(5), 'o' as libc::c_char);
- assert_eq!(*buf.offset(6), 0);
- })
- }
- }
-
- #[test]
- fn test_as_bytes() {
- let c_str = "hello".to_c_str();
- assert_eq!(c_str.as_bytes(), bytes!("hello", 0));
- let c_str = "".to_c_str();
- assert_eq!(c_str.as_bytes(), bytes!(0));
- let c_str = bytes!("foo", 0xff).to_c_str();
- assert_eq!(c_str.as_bytes(), bytes!("foo", 0xff, 0));
- }
-
- #[test]
- #[should_fail]
- fn test_as_bytes_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.as_bytes();
- }
-
- #[test]
- fn test_as_str() {
- let c_str = "hello".to_c_str();
- assert_eq!(c_str.as_str(), Some("hello"));
- let c_str = "".to_c_str();
- assert_eq!(c_str.as_str(), Some(""));
- let c_str = bytes!("foo", 0xff).to_c_str();
- assert_eq!(c_str.as_str(), None);
- let c_str = unsafe { CString::new(ptr::null(), false) };
- assert_eq!(c_str.as_str(), None);
- }
-}
-
-#[cfg(test)]
-mod bench {
- use iter::range;
- use libc;
- use option::Some;
- use ptr;
- use extra::test::BenchHarness;
-
- #[inline]
- fn check(s: &str, c_str: *libc::c_char) {
- s.as_imm_buf(|s_buf, s_len| {
- for i in range(0, s_len) {
- unsafe {
- assert_eq!(
- *ptr::offset(s_buf, i as int) as libc::c_char,
- *ptr::offset(c_str, i as int));
- }
- }
- })
- }
-
- static s_short: &'static str = "Mary";
- static s_medium: &'static str = "Mary had a little lamb";
- static s_long: &'static str = "\
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb";
-
- fn bench_to_str(bh: &mut BenchHarness, s: &str) {
- bh.iter(|| {
- let c_str = s.to_c_str();
- c_str.with_ref(|c_str_buf| check(s, c_str_buf))
- })
- }
-
- #[bench]
- fn bench_to_c_str_short(bh: &mut BenchHarness) {
- bench_to_str(bh, s_short)
- }
-
- #[bench]
- fn bench_to_c_str_medium(bh: &mut BenchHarness) {
- bench_to_str(bh, s_medium)
- }
-
- #[bench]
- fn bench_to_c_str_long(bh: &mut BenchHarness) {
- bench_to_str(bh, s_long)
- }
-
- fn bench_to_c_str_unchecked(bh: &mut BenchHarness, s: &str) {
- bh.iter(|| {
- let c_str = unsafe { s.to_c_str_unchecked() };
- c_str.with_ref(|c_str_buf| check(s, c_str_buf))
- })
- }
-
- #[bench]
- fn bench_to_c_str_unchecked_short(bh: &mut BenchHarness) {
- bench_to_c_str_unchecked(bh, s_short)
- }
-
- #[bench]
- fn bench_to_c_str_unchecked_medium(bh: &mut BenchHarness) {
- bench_to_c_str_unchecked(bh, s_medium)
- }
-
- #[bench]
- fn bench_to_c_str_unchecked_long(bh: &mut BenchHarness) {
- bench_to_c_str_unchecked(bh, s_long)
- }
-
- fn bench_with_c_str(bh: &mut BenchHarness, s: &str) {
- bh.iter(|| {
- s.with_c_str(|c_str_buf| check(s, c_str_buf))
- })
- }
-
- #[bench]
- fn bench_with_c_str_short(bh: &mut BenchHarness) {
- bench_with_c_str(bh, s_short)
- }
-
- #[bench]
- fn bench_with_c_str_medium(bh: &mut BenchHarness) {
- bench_with_c_str(bh, s_medium)
- }
-
- #[bench]
- fn bench_with_c_str_long(bh: &mut BenchHarness) {
- bench_with_c_str(bh, s_long)
- }
-
- fn bench_with_c_str_unchecked(bh: &mut BenchHarness, s: &str) {
- bh.iter(|| {
- unsafe {
- s.with_c_str_unchecked(|c_str_buf| check(s, c_str_buf))
- }
- })
- }
-
- #[bench]
- fn bench_with_c_str_unchecked_short(bh: &mut BenchHarness) {
- bench_with_c_str_unchecked(bh, s_short)
- }
-
- #[bench]
- fn bench_with_c_str_unchecked_medium(bh: &mut BenchHarness) {
- bench_with_c_str_unchecked(bh, s_medium)
- }
-
- #[bench]
- fn bench_with_c_str_unchecked_long(bh: &mut BenchHarness) {
- bench_with_c_str_unchecked(bh, s_long)
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unsafe casting functions
-
-use ptr::RawPtr;
-use mem;
-use unstable::intrinsics;
-use ptr::copy_nonoverlapping_memory;
-
-/// Casts the value at `src` to U. The two types must have the same length.
-#[inline]
-pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
- let mut dest: U = intrinsics::uninit();
- let dest_ptr: *mut u8 = transmute(&mut dest);
- let src_ptr: *u8 = transmute(src);
- copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
- dest
-}
-
-/**
- * Move a thing into the void
- *
- * The forget function will take ownership of the provided value but neglect
- * to run any required cleanup or memory-management operations on it. This
- * can be used for various acts of magick.
- */
-#[inline]
-pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }
-
-/**
- * Force-increment the reference count on a shared box. If used
- * carelessly, this can leak the box.
- */
-#[inline]
-pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
-
-/**
- * Transform a value of one type into a value of another type.
- * Both types must have the same size and alignment.
- *
- * # Example
- *
- * ```rust
- * let v: &[u8] = transmute("L");
- * assert!(v == [76u8]);
- * ```
- */
-#[inline]
-pub unsafe fn transmute<L, G>(thing: L) -> G {
- intrinsics::transmute(thing)
-}
-
-/// Coerce an immutable reference to be mutable.
-#[inline]
-pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
-
-/// Coerce a mutable reference to be immutable.
-#[inline]
-pub unsafe fn transmute_immut<'a,T>(ptr: &'a mut T) -> &'a T {
- transmute(ptr)
-}
-
-/// Coerce a borrowed pointer to have an arbitrary associated region.
-#[inline]
-pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
- transmute(ptr)
-}
-
-/// Coerce an immutable reference to be mutable.
-#[inline]
-pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
- transmute(ptr)
-}
-
-/// Coerce an immutable reference to be mutable.
-#[inline]
-pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
- transmute(ptr)
-}
-
-/// Coerce a borrowed mutable pointer to have an arbitrary associated region.
-#[inline]
-pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
- transmute(ptr)
-}
-
-/// Transforms lifetime of the second pointer to match the first.
-#[inline]
-pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
- transmute_region(ptr)
-}
-
-/// Transforms lifetime of the second pointer to match the first.
-#[inline]
-pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
- transmute_mut_region(ptr)
-}
-
-/// Transforms lifetime of the second pointer to match the first.
-#[inline]
-pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
- transmute_region(ptr)
-}
-
-
-/****************************************************************************
- * Tests
- ****************************************************************************/
-
-#[cfg(test)]
-mod tests {
- use cast::{bump_box_refcount, transmute};
- use unstable::raw;
-
- #[test]
- fn test_transmute_copy() {
- assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
- }
-
- #[test]
- fn test_bump_box_refcount() {
- unsafe {
- let box = @~"box box box"; // refcount 1
- bump_box_refcount(box); // refcount 2
- let ptr: *int = transmute(box); // refcount 2
- let _box1: @~str = ::cast::transmute_copy(&ptr);
- let _box2: @~str = ::cast::transmute_copy(&ptr);
- assert!(*_box1 == ~"box box box");
- assert!(*_box2 == ~"box box box");
- // Will destroy _box1 and _box2. Without the bump, this would
- // use-after-free. With too many bumps, it would leak.
- }
- }
-
- #[test]
- fn test_transmute() {
- unsafe {
- let x = @100u8;
- let x: *raw::Box<u8> = transmute(x);
- assert!((*x).data == 100);
- let _x: @int = transmute(x);
- }
- }
-
- #[test]
- fn test_transmute2() {
- unsafe {
- assert_eq!(~[76u8], transmute(~"L"));
- }
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Types dealing with dynamic mutability
-
-use prelude::*;
-use cast;
-use util::NonCopyable;
-
-
-/*
-A dynamic, mutable location.
-
-Similar to a mutable option type, but friendlier.
-*/
-
-#[no_freeze]
-#[deriving(Clone, DeepClone, Eq)]
-#[allow(missing_doc)]
-pub struct Cell<T> {
- priv value: Option<T>
-}
-
-impl<T> Cell<T> {
- /// Creates a new full cell with the given value.
- pub fn new(value: T) -> Cell<T> {
- Cell { value: Some(value) }
- }
-
- /// Yields the value, failing if the cell is empty.
- pub fn take(&self) -> T {
- let this = unsafe { cast::transmute_mut(self) };
- if this.is_empty() {
- fail!("attempt to take an empty cell");
- }
-
- this.value.take_unwrap()
- }
-
- /// Yields the value if the cell is full, or `None` if it is empty.
- pub fn take_opt(&self) -> Option<T> {
- let this = unsafe { cast::transmute_mut(self) };
- this.value.take()
- }
-
- /// Returns true if the cell is empty and false if the cell is full.
- pub fn is_empty(&self) -> bool {
- self.value.is_none()
- }
-}
-
-#[test]
-fn test_basic() {
- let value_cell = Cell::new(~10);
- assert!(!value_cell.is_empty());
- let value = value_cell.take();
- assert!(value == ~10);
- assert!(value_cell.is_empty());
-}
-
-#[test]
-#[should_fail]
-fn test_take_empty() {
- let value_cell: Cell<~int> = Cell::new(~0);
- value_cell.take();
- value_cell.take();
-}
-
-
-/// A mutable memory location with dynamically checked borrow rules
-#[no_freeze]
-pub struct RefCell<T> {
- priv value: T,
- priv borrow: BorrowFlag,
- priv nc: NonCopyable
-}
-
-// Values [1, MAX-1] represent the number of `Ref` active
-// (will not outgrow its range since `uint` is the size of the address space)
-type BorrowFlag = uint;
-static UNUSED: BorrowFlag = 0;
-static WRITING: BorrowFlag = -1;
-
-impl<T> RefCell<T> {
- /// Create a new `RefCell` containing `value`
- pub fn new(value: T) -> RefCell<T> {
- RefCell {
- value: value,
- borrow: UNUSED,
- nc: NonCopyable
- }
- }
-
- /// Consumes the `RefCell`, returning the wrapped value.
- pub fn unwrap(self) -> T {
- assert!(self.borrow == UNUSED);
- self.value
- }
-
- unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
- cast::transmute_mut(self)
- }
-
- /// Attempts to immutably borrow the wrapped value.
- ///
- /// The borrow lasts until the returned `Ref` exits scope. Multiple
- /// immutable borrows can be taken out at the same time.
- ///
- /// Returns `None` if the value is currently mutably borrowed.
- pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
- match self.borrow {
- WRITING => None,
- _ => {
- unsafe { self.as_mut().borrow += 1; }
- Some(Ref { parent: self })
- }
- }
- }
-
- /// Immutably borrows the wrapped value.
- ///
- /// The borrow lasts until the returned `Ref` exits scope. Multiple
- /// immutable borrows can be taken out at the same time.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently mutably borrowed.
- pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
- match self.try_borrow() {
- Some(ptr) => ptr,
- None => fail!("RefCell<T> already mutably borrowed")
- }
- }
-
- /// Mutably borrows the wrapped value.
- ///
- /// The borrow lasts untile the returned `RefMut` exits scope. The value
- /// cannot be borrowed while this borrow is active.
- ///
- /// Returns `None` if the value is currently borrowed.
- pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
- match self.borrow {
- UNUSED => unsafe {
- let mut_self = self.as_mut();
- mut_self.borrow = WRITING;
- Some(RefMut { parent: mut_self })
- },
- _ => None
- }
- }
-
- /// Mutably borrows the wrapped value.
- ///
- /// The borrow lasts untile the returned `RefMut` exits scope. The value
- /// cannot be borrowed while this borrow is active.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently borrowed.
- pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
- match self.try_borrow_mut() {
- Some(ptr) => ptr,
- None => fail!("RefCell<T> already borrowed")
- }
- }
-
- /// Immutably borrows the wrapped value and applies `blk` to it.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently mutably borrowed.
- #[inline]
- pub fn with<U>(&self, blk: |&T| -> U) -> U {
- let ptr = self.borrow();
- blk(ptr.get())
- }
-
- /// Mutably borrows the wrapped value and applies `blk` to it.
- ///
- /// # Failure
- ///
- /// Fails if the value is currently borrowed.
- #[inline]
- pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
- let mut ptr = self.borrow_mut();
- blk(ptr.get())
- }
-}
-
-impl<T: Clone> Clone for RefCell<T> {
- fn clone(&self) -> RefCell<T> {
- let x = self.borrow();
- RefCell::new(x.get().clone())
- }
-}
-
-impl<T: DeepClone> DeepClone for RefCell<T> {
- fn deep_clone(&self) -> RefCell<T> {
- let x = self.borrow();
- RefCell::new(x.get().deep_clone())
- }
-}
-
-impl<T: Eq> Eq for RefCell<T> {
- fn eq(&self, other: &RefCell<T>) -> bool {
- let a = self.borrow();
- let b = other.borrow();
- a.get() == b.get()
- }
-}
-
-/// Wraps a borrowed reference to a value in a `RefCell` box.
-pub struct Ref<'box, T> {
- priv parent: &'box RefCell<T>
-}
-
-#[unsafe_destructor]
-impl<'box, T> Drop for Ref<'box, T> {
- fn drop(&mut self) {
- assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
- unsafe { self.parent.as_mut().borrow -= 1; }
- }
-}
-
-impl<'box, T> Ref<'box, T> {
- /// Retrieve an immutable reference to the stored value.
- #[inline]
- pub fn get<'a>(&'a self) -> &'a T {
- &self.parent.value
- }
-}
-
-/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
-pub struct RefMut<'box, T> {
- priv parent: &'box mut RefCell<T>
-}
-
-#[unsafe_destructor]
-impl<'box, T> Drop for RefMut<'box, T> {
- fn drop(&mut self) {
- assert!(self.parent.borrow == WRITING);
- self.parent.borrow = UNUSED;
- }
-}
-
-impl<'box, T> RefMut<'box, T> {
- /// Retrieve a mutable reference to the stored value.
- #[inline]
- pub fn get<'a>(&'a mut self) -> &'a mut T {
- &mut self.parent.value
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn double_imm_borrow() {
- let x = RefCell::new(0);
- let _b1 = x.borrow();
- x.borrow();
- }
-
- #[test]
- fn no_mut_then_imm_borrow() {
- let x = RefCell::new(0);
- let _b1 = x.borrow_mut();
- assert!(x.try_borrow().is_none());
- }
-
- #[test]
- fn no_imm_then_borrow_mut() {
- let x = RefCell::new(0);
- let _b1 = x.borrow();
- assert!(x.try_borrow_mut().is_none());
- }
-
- #[test]
- fn no_double_borrow_mut() {
- let x = RefCell::new(0);
- let _b1 = x.borrow_mut();
- assert!(x.try_borrow_mut().is_none());
- }
-
- #[test]
- fn imm_release_borrow_mut() {
- let x = RefCell::new(0);
- {
- let _b1 = x.borrow();
- }
- x.borrow_mut();
- }
-
- #[test]
- fn mut_release_borrow_mut() {
- let x = RefCell::new(0);
- {
- let _b1 = x.borrow_mut();
- }
- x.borrow();
- }
-
- #[test]
- fn double_borrow_single_release_no_borrow_mut() {
- let x = RefCell::new(0);
- let _b1 = x.borrow();
- {
- let _b2 = x.borrow();
- }
- assert!(x.try_borrow_mut().is_none());
- }
-
- #[test]
- fn with_ok() {
- let x = RefCell::new(0);
- assert_eq!(1, x.with(|x| *x+1));
- }
-
- #[test]
- #[should_fail]
- fn mut_borrow_with() {
- let x = RefCell::new(0);
- let _b1 = x.borrow_mut();
- x.with(|x| *x+1);
- }
-
- #[test]
- fn borrow_with() {
- let x = RefCell::new(0);
- let _b1 = x.borrow();
- assert_eq!(1, x.with(|x| *x+1));
- }
-
- #[test]
- fn with_mut_ok() {
- let x = RefCell::new(0);
- x.with_mut(|x| *x += 1);
- let b = x.borrow();
- assert_eq!(1, *b.get());
- }
-
- #[test]
- #[should_fail]
- fn borrow_with_mut() {
- let x = RefCell::new(0);
- let _b = x.borrow();
- x.with_mut(|x| *x += 1);
- }
-
- #[test]
- #[should_fail]
- fn discard_doesnt_unborrow() {
- let x = RefCell::new(0);
- let _b = x.borrow();
- let _ = _b;
- let _b = x.borrow_mut();
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Utilities for manipulating the char type
-
-use cast::transmute;
-use option::{None, Option, Some};
-use iter::{Iterator, range_step};
-use str::StrSlice;
-use unicode::{derived_property, property, general_category, decompose};
-use to_str::ToStr;
-use str;
-
-#[cfg(test)] use str::OwnedStr;
-
-#[cfg(not(test))] use cmp::{Eq, Ord};
-#[cfg(not(test))] use default::Default;
-#[cfg(not(test))] use num::Zero;
-
-// UTF-8 ranges and tags for encoding characters
-static TAG_CONT: uint = 128u;
-static MAX_ONE_B: uint = 128u;
-static TAG_TWO_B: uint = 192u;
-static MAX_TWO_B: uint = 2048u;
-static TAG_THREE_B: uint = 224u;
-static MAX_THREE_B: uint = 65536u;
-static TAG_FOUR_B: uint = 240u;
-
-/*
- Lu Uppercase_Letter an uppercase letter
- Ll Lowercase_Letter a lowercase letter
- Lt Titlecase_Letter a digraphic character, with first part uppercase
- Lm Modifier_Letter a modifier letter
- Lo Other_Letter other letters, including syllables and ideographs
- Mn Nonspacing_Mark a nonspacing combining mark (zero advance width)
- Mc Spacing_Mark a spacing combining mark (positive advance width)
- Me Enclosing_Mark an enclosing combining mark
- Nd Decimal_Number a decimal digit
- Nl Letter_Number a letterlike numeric character
- No Other_Number a numeric character of other type
- Pc Connector_Punctuation a connecting punctuation mark, like a tie
- Pd Dash_Punctuation a dash or hyphen punctuation mark
- Ps Open_Punctuation an opening punctuation mark (of a pair)
- Pe Close_Punctuation a closing punctuation mark (of a pair)
- Pi Initial_Punctuation an initial quotation mark
- Pf Final_Punctuation a final quotation mark
- Po Other_Punctuation a punctuation mark of other type
- Sm Math_Symbol a symbol of primarily mathematical use
- Sc Currency_Symbol a currency sign
- Sk Modifier_Symbol a non-letterlike modifier symbol
- So Other_Symbol a symbol of other type
- Zs Space_Separator a space character (of various non-zero widths)
- Zl Line_Separator U+2028 LINE SEPARATOR only
- Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only
- Cc Control a C0 or C1 control code
- Cf Format a format control character
- Cs Surrogate a surrogate code point
- Co Private_Use a private-use character
- Cn Unassigned a reserved unassigned code point or a noncharacter
-*/
-
-/// The highest valid code point
-pub static MAX: char = '\U0010ffff';
-
-/// Convert from `u32` to a character.
-pub fn from_u32(i: u32) -> Option<char> {
- // catch out-of-bounds and surrogates
- if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
- None
- } else {
- Some(unsafe { transmute(i) })
- }
-}
-
-/// Returns whether the specified character is considered a unicode alphabetic
-/// character
-pub fn is_alphabetic(c: char) -> bool { derived_property::Alphabetic(c) }
-#[allow(missing_doc)]
-pub fn is_XID_start(c: char) -> bool { derived_property::XID_Start(c) }
-#[allow(missing_doc)]
-pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
-
-///
-/// Indicates whether a character is in lower case, defined
-/// in terms of the Unicode Derived Core Property 'Lowercase'.
-///
-#[inline]
-pub fn is_lowercase(c: char) -> bool { derived_property::Lowercase(c) }
-
-///
-/// Indicates whether a character is in upper case, defined
-/// in terms of the Unicode Derived Core Property 'Uppercase'.
-///
-#[inline]
-pub fn is_uppercase(c: char) -> bool { derived_property::Uppercase(c) }
-
-///
-/// Indicates whether a character is whitespace. Whitespace is defined in
-/// terms of the Unicode Property 'White_Space'.
-///
-#[inline]
-pub fn is_whitespace(c: char) -> bool {
- // As an optimization ASCII whitespace characters are checked separately
- c == ' '
- || ('\x09' <= c && c <= '\x0d')
- || property::White_Space(c)
-}
-
-///
-/// Indicates whether a character is alphanumeric. Alphanumericness is
-/// defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No'
-/// and the Derived Core Property 'Alphabetic'.
-///
-#[inline]
-pub fn is_alphanumeric(c: char) -> bool {
- derived_property::Alphabetic(c)
- || general_category::Nd(c)
- || general_category::Nl(c)
- || general_category::No(c)
-}
-
-///
-/// Indicates whether a character is a control character. Control
-/// characters are defined in terms of the Unicode General Category
-/// 'Cc'.
-///
-#[inline]
-pub fn is_control(c: char) -> bool { general_category::Cc(c) }
-
-/// Indicates whether the character is numeric (Nd, Nl, or No)
-#[inline]
-pub fn is_digit(c: char) -> bool {
- general_category::Nd(c)
- || general_category::Nl(c)
- || general_category::No(c)
-}
-
-///
-/// Checks if a character parses as a numeric digit in the given radix.
-/// Compared to `is_digit()`, this function only recognizes the
-/// characters `0-9`, `a-z` and `A-Z`.
-///
-/// # Return value
-///
-/// Returns `true` if `c` is a valid digit under `radix`, and `false`
-/// otherwise.
-///
-/// # Failure
-///
-/// Fails if given a `radix` > 36.
-///
-/// # Note
-///
-/// This just wraps `to_digit()`.
-///
-#[inline]
-pub fn is_digit_radix(c: char, radix: uint) -> bool {
- match to_digit(c, radix) {
- Some(_) => true,
- None => false,
- }
-}
-
-///
-/// Convert a char to the corresponding digit.
-///
-/// # Return value
-///
-/// If `c` is between '0' and '9', the corresponding value
-/// between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
-/// 'b' or 'B', 11, etc. Returns none if the char does not
-/// refer to a digit in the given radix.
-///
-/// # Failure
-///
-/// Fails if given a `radix` outside the range `[0..36]`.
-///
-#[inline]
-pub fn to_digit(c: char, radix: uint) -> Option<uint> {
- if radix > 36 {
- fail!("to_digit: radix {} is too high (maximum 36)", radix);
- }
- let val = match c {
- '0' .. '9' => c as uint - ('0' as uint),
- 'a' .. 'z' => c as uint + 10u - ('a' as uint),
- 'A' .. 'Z' => c as uint + 10u - ('A' as uint),
- _ => return None,
- };
- if val < radix { Some(val) }
- else { None }
-}
-
-///
-/// Converts a number to the character representing it.
-///
-/// # Return value
-///
-/// Returns `Some(char)` if `num` represents one digit under `radix`,
-/// using one character of `0-9` or `a-z`, or `None` if it doesn't.
-///
-/// # Failure
-///
-/// Fails if given an `radix` > 36.
-///
-#[inline]
-pub fn from_digit(num: uint, radix: uint) -> Option<char> {
- if radix > 36 {
- fail!("from_digit: radix {} is to high (maximum 36)", num);
- }
- if num < radix {
- unsafe {
- if num < 10 {
- Some(transmute(('0' as uint + num) as u32))
- } else {
- Some(transmute(('a' as uint + num - 10u) as u32))
- }
- }
- } else {
- None
- }
-}
-
-// Constants from Unicode 6.2.0 Section 3.12 Conjoining Jamo Behavior
-static S_BASE: uint = 0xAC00;
-static L_BASE: uint = 0x1100;
-static V_BASE: uint = 0x1161;
-static T_BASE: uint = 0x11A7;
-static L_COUNT: uint = 19;
-static V_COUNT: uint = 21;
-static T_COUNT: uint = 28;
-static N_COUNT: uint = (V_COUNT * T_COUNT);
-static S_COUNT: uint = (L_COUNT * N_COUNT);
-
-// Decompose a precomposed Hangul syllable
-fn decompose_hangul(s: char, f: |char|) {
- let si = s as uint - S_BASE;
-
- let li = si / N_COUNT;
- unsafe {
- f(transmute((L_BASE + li) as u32));
-
- let vi = (si % N_COUNT) / T_COUNT;
- f(transmute((V_BASE + vi) as u32));
-
- let ti = si % T_COUNT;
- if ti > 0 {
- f(transmute((T_BASE + ti) as u32));
- }
- }
-}
-
-/// Returns the canonical decompostion of a character
-pub fn decompose_canonical(c: char, f: |char|) {
- if (c as uint) < S_BASE || (c as uint) >= (S_BASE + S_COUNT) {
- decompose::canonical(c, f);
- } else {
- decompose_hangul(c, f);
- }
-}
-
-/// Returns the compatibility decompostion of a character
-pub fn decompose_compatible(c: char, f: |char|) {
- if (c as uint) < S_BASE || (c as uint) >= (S_BASE + S_COUNT) {
- decompose::compatibility(c, f);
- } else {
- decompose_hangul(c, f);
- }
-}
-
-///
-/// Return the hexadecimal unicode escape of a char.
-///
-/// The rules are as follows:
-///
-/// - chars in [0,0xff] get 2-digit escapes: `\\xNN`
-/// - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN`
-/// - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN`
-///
-pub fn escape_unicode(c: char, f: |char|) {
- // avoid calling str::to_str_radix because we don't really need to allocate
- // here.
- f('\\');
- let pad = match () {
- _ if c <= '\xff' => { f('x'); 2 }
- _ if c <= '\uffff' => { f('u'); 4 }
- _ => { f('U'); 8 }
- };
- for offset in range_step::<i32>(4 * (pad - 1), -1, -4) {
- unsafe {
- match ((c as i32) >> offset) & 0xf {
- i @ 0 .. 9 => { f(transmute('0' as i32 + i)); }
- i => { f(transmute('a' as i32 + (i - 10))); }
- }
- }
- }
-}
-
-///
-/// Return a 'default' ASCII and C++11-like char-literal escape of a char.
-///
-/// The default is chosen with a bias toward producing literals that are
-/// legal in a variety of languages, including C++11 and similar C-family
-/// languages. The exact rules are:
-///
-/// - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
-/// - Single-quote, double-quote and backslash chars are backslash-escaped.
-/// - Any other chars in the range [0x20,0x7e] are not escaped.
-/// - Any other chars are given hex unicode escapes; see `escape_unicode`.
-///
-pub fn escape_default(c: char, f: |char|) {
- match c {
- '\t' => { f('\\'); f('t'); }
- '\r' => { f('\\'); f('r'); }
- '\n' => { f('\\'); f('n'); }
- '\\' => { f('\\'); f('\\'); }
- '\'' => { f('\\'); f('\''); }
- '"' => { f('\\'); f('"'); }
- '\x20' .. '\x7e' => { f(c); }
- _ => c.escape_unicode(f),
- }
-}
-
-/// Returns the amount of bytes this character would need if encoded in utf8
-pub fn len_utf8_bytes(c: char) -> uint {
- static MAX_ONE_B: uint = 128u;
- static MAX_TWO_B: uint = 2048u;
- static MAX_THREE_B: uint = 65536u;
- static MAX_FOUR_B: uint = 2097152u;
-
- let code = c as uint;
- match () {
- _ if code < MAX_ONE_B => 1u,
- _ if code < MAX_TWO_B => 2u,
- _ if code < MAX_THREE_B => 3u,
- _ if code < MAX_FOUR_B => 4u,
- _ => fail!("invalid character!"),
- }
-}
-
-impl ToStr for char {
- #[inline]
- fn to_str(&self) -> ~str {
- str::from_char(*self)
- }
-}
-
-#[allow(missing_doc)]
-pub trait Char {
- fn is_alphabetic(&self) -> bool;
- fn is_XID_start(&self) -> bool;
- fn is_XID_continue(&self) -> bool;
- fn is_lowercase(&self) -> bool;
- fn is_uppercase(&self) -> bool;
- fn is_whitespace(&self) -> bool;
- fn is_alphanumeric(&self) -> bool;
- fn is_control(&self) -> bool;
- fn is_digit(&self) -> bool;
- fn is_digit_radix(&self, radix: uint) -> bool;
- fn to_digit(&self, radix: uint) -> Option<uint>;
- fn from_digit(num: uint, radix: uint) -> Option<char>;
- fn escape_unicode(&self, f: |char|);
- fn escape_default(&self, f: |char|);
- fn len_utf8_bytes(&self) -> uint;
-
- /// Encodes this character as utf-8 into the provided byte-buffer. The
- /// buffer must be at least 4 bytes long or a runtime failure will occur.
- ///
- /// This will then return the number of characters written to the slice.
- fn encode_utf8(&self, dst: &mut [u8]) -> uint;
-}
-
-impl Char for char {
- fn is_alphabetic(&self) -> bool { is_alphabetic(*self) }
-
- fn is_XID_start(&self) -> bool { is_XID_start(*self) }
-
- fn is_XID_continue(&self) -> bool { is_XID_continue(*self) }
-
- fn is_lowercase(&self) -> bool { is_lowercase(*self) }
-
- fn is_uppercase(&self) -> bool { is_uppercase(*self) }
-
- fn is_whitespace(&self) -> bool { is_whitespace(*self) }
-
- fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
-
- fn is_control(&self) -> bool { is_control(*self) }
-
- fn is_digit(&self) -> bool { is_digit(*self) }
-
- fn is_digit_radix(&self, radix: uint) -> bool { is_digit_radix(*self, radix) }
-
- fn to_digit(&self, radix: uint) -> Option<uint> { to_digit(*self, radix) }
-
- fn from_digit(num: uint, radix: uint) -> Option<char> { from_digit(num, radix) }
-
- fn escape_unicode(&self, f: |char|) { escape_unicode(*self, f) }
-
- fn escape_default(&self, f: |char|) { escape_default(*self, f) }
-
- fn len_utf8_bytes(&self) -> uint { len_utf8_bytes(*self) }
-
- fn encode_utf8<'a>(&self, dst: &'a mut [u8]) -> uint {
- let code = *self as uint;
- if code < MAX_ONE_B {
- dst[0] = code as u8;
- return 1;
- } else if code < MAX_TWO_B {
- dst[0] = (code >> 6u & 31u | TAG_TWO_B) as u8;
- dst[1] = (code & 63u | TAG_CONT) as u8;
- return 2;
- } else if code < MAX_THREE_B {
- dst[0] = (code >> 12u & 15u | TAG_THREE_B) as u8;
- dst[1] = (code >> 6u & 63u | TAG_CONT) as u8;
- dst[2] = (code & 63u | TAG_CONT) as u8;
- return 3;
- } else {
- dst[0] = (code >> 18u & 7u | TAG_FOUR_B) as u8;
- dst[1] = (code >> 12u & 63u | TAG_CONT) as u8;
- dst[2] = (code >> 6u & 63u | TAG_CONT) as u8;
- dst[3] = (code & 63u | TAG_CONT) as u8;
- return 4;
- }
- }
-}
-
-#[cfg(not(test))]
-impl Eq for char {
- #[inline]
- fn eq(&self, other: &char) -> bool { (*self) == (*other) }
-}
-
-#[cfg(not(test))]
-impl Ord for char {
- #[inline]
- fn lt(&self, other: &char) -> bool { *self < *other }
-}
-
-#[cfg(not(test))]
-impl Default for char {
- #[inline]
- fn default() -> char { '\x00' }
-}
-
-#[cfg(not(test))]
-impl Zero for char {
- #[inline]
- fn zero() -> char { '\x00' }
-
- #[inline]
- fn is_zero(&self) -> bool { *self == '\x00' }
-}
-
-#[test]
-fn test_is_lowercase() {
- assert!('a'.is_lowercase());
- assert!('ö'.is_lowercase());
- assert!('ß'.is_lowercase());
- assert!(!'Ü'.is_lowercase());
- assert!(!'P'.is_lowercase());
-}
-
-#[test]
-fn test_is_uppercase() {
- assert!(!'h'.is_uppercase());
- assert!(!'ä'.is_uppercase());
- assert!(!'ß'.is_uppercase());
- assert!('Ö'.is_uppercase());
- assert!('T'.is_uppercase());
-}
-
-#[test]
-fn test_is_whitespace() {
- assert!(' '.is_whitespace());
- assert!('\u2007'.is_whitespace());
- assert!('\t'.is_whitespace());
- assert!('\n'.is_whitespace());
- assert!(!'a'.is_whitespace());
- assert!(!'_'.is_whitespace());
- assert!(!'\u0000'.is_whitespace());
-}
-
-#[test]
-fn test_to_digit() {
- assert_eq!('0'.to_digit(10u), Some(0u));
- assert_eq!('1'.to_digit(2u), Some(1u));
- assert_eq!('2'.to_digit(3u), Some(2u));
- assert_eq!('9'.to_digit(10u), Some(9u));
- assert_eq!('a'.to_digit(16u), Some(10u));
- assert_eq!('A'.to_digit(16u), Some(10u));
- assert_eq!('b'.to_digit(16u), Some(11u));
- assert_eq!('B'.to_digit(16u), Some(11u));
- assert_eq!('z'.to_digit(36u), Some(35u));
- assert_eq!('Z'.to_digit(36u), Some(35u));
- assert_eq!(' '.to_digit(10u), None);
- assert_eq!('$'.to_digit(36u), None);
-}
-
-#[test]
-fn test_is_control() {
- assert!('\u0000'.is_control());
- assert!('\u0003'.is_control());
- assert!('\u0006'.is_control());
- assert!('\u0009'.is_control());
- assert!('\u007f'.is_control());
- assert!('\u0092'.is_control());
- assert!(!'\u0020'.is_control());
- assert!(!'\u0055'.is_control());
- assert!(!'\u0068'.is_control());
-}
-
-#[test]
-fn test_is_digit() {
- assert!('2'.is_digit());
- assert!('7'.is_digit());
- assert!(!'c'.is_digit());
- assert!(!'i'.is_digit());
- assert!(!'z'.is_digit());
- assert!(!'Q'.is_digit());
-}
-
-#[test]
-fn test_escape_default() {
- fn string(c: char) -> ~str {
- let mut result = ~"";
- escape_default(c, |c| { result.push_char(c); });
- return result;
- }
- assert_eq!(string('\n'), ~"\\n");
- assert_eq!(string('\r'), ~"\\r");
- assert_eq!(string('\''), ~"\\'");
- assert_eq!(string('"'), ~"\\\"");
- assert_eq!(string(' '), ~" ");
- assert_eq!(string('a'), ~"a");
- assert_eq!(string('~'), ~"~");
- assert_eq!(string('\x00'), ~"\\x00");
- assert_eq!(string('\x1f'), ~"\\x1f");
- assert_eq!(string('\x7f'), ~"\\x7f");
- assert_eq!(string('\xff'), ~"\\xff");
- assert_eq!(string('\u011b'), ~"\\u011b");
- assert_eq!(string('\U0001d4b6'), ~"\\U0001d4b6");
-}
-
-#[test]
-fn test_escape_unicode() {
- fn string(c: char) -> ~str {
- let mut result = ~"";
- escape_unicode(c, |c| { result.push_char(c); });
- return result;
- }
- assert_eq!(string('\x00'), ~"\\x00");
- assert_eq!(string('\n'), ~"\\x0a");
- assert_eq!(string(' '), ~"\\x20");
- assert_eq!(string('a'), ~"\\x61");
- assert_eq!(string('\u011b'), ~"\\u011b");
- assert_eq!(string('\U0001d4b6'), ~"\\U0001d4b6");
-}
-
-#[test]
-fn test_to_str() {
- let s = 't'.to_str();
- assert_eq!(s, ~"t");
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[doc(hidden)];
-
-use libc::c_void;
-use ptr;
-use unstable::intrinsics::TyDesc;
-use unstable::raw;
-
-type DropGlue<'self> = 'self |**TyDesc, *c_void|;
-
-/*
- * Box annihilation
- *
- * This runs at task death to free all boxes.
- */
-
-struct AnnihilateStats {
- n_total_boxes: uint,
- n_unique_boxes: uint,
- n_bytes_freed: uint
-}
-
-unsafe fn each_live_alloc(read_next_before: bool,
- f: |box: *mut raw::Box<()>, uniq: bool| -> bool)
- -> bool {
- //! Walks the internal list of allocations
-
- use managed;
- use rt::local_heap;
-
- let mut box = local_heap::live_allocs();
- while box != ptr::mut_null() {
- let next_before = (*box).next;
- let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;
-
- if !f(box as *mut raw::Box<()>, uniq) {
- return false;
- }
-
- if read_next_before {
- box = next_before;
- } else {
- box = (*box).next;
- }
- }
- return true;
-}
-
-#[cfg(unix)]
-fn debug_mem() -> bool {
- // XXX: Need to port the environment struct to newsched
- false
-}
-
-#[cfg(windows)]
-fn debug_mem() -> bool {
- false
-}
-
-/// Destroys all managed memory (i.e. @ boxes) held by the current task.
-pub unsafe fn annihilate() {
- use rt::local_heap::local_free;
- use mem;
- use managed;
-
- let mut stats = AnnihilateStats {
- n_total_boxes: 0,
- n_unique_boxes: 0,
- n_bytes_freed: 0
- };
-
- // Pass 1: Make all boxes immortal.
- //
- // In this pass, nothing gets freed, so it does not matter whether
- // we read the next field before or after the callback.
- each_live_alloc(true, |box, uniq| {
- stats.n_total_boxes += 1;
- if uniq {
- stats.n_unique_boxes += 1;
- } else {
- (*box).ref_count = managed::RC_IMMORTAL;
- }
- true
- });
-
- // Pass 2: Drop all boxes.
- //
- // In this pass, unique-managed boxes may get freed, but not
- // managed boxes, so we must read the `next` field *after* the
- // callback, as the original value may have been freed.
- each_live_alloc(false, |box, uniq| {
- if !uniq {
- let tydesc = (*box).type_desc;
- let data = &(*box).data as *();
- ((*tydesc).drop_glue)(data as *i8);
- }
- true
- });
-
- // Pass 3: Free all boxes.
- //
- // In this pass, managed boxes may get freed (but not
- // unique-managed boxes, though I think that none of those are
- // left), so we must read the `next` field before, since it will
- // not be valid after.
- each_live_alloc(true, |box, uniq| {
- if !uniq {
- stats.n_bytes_freed +=
- (*((*box).type_desc)).size
- + mem::size_of::<raw::Box<()>>();
- local_free(box as *i8);
- }
- true
- });
-
- if debug_mem() {
- // We do logging here w/o allocation.
- debug!("annihilator stats:\n \
- total boxes: {}\n \
- unique boxes: {}\n \
- bytes freed: {}",
- stats.n_total_boxes, stats.n_unique_boxes, stats.n_bytes_freed);
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! The Clone trait for types that cannot be "implicitly copied"
-
-In Rust, some simple types are "implicitly copyable" and when you
-assign them or pass them as arguments, the receiver will get a copy,
-leaving the original value in place. These types do not require
-allocation to copy and do not have finalizers (i.e. they do not
-contain owned boxes or implement `Drop`), so the compiler considers
-them cheap and safe to copy. For other types copies must be made
-explicitly, by convention implementing the `Clone` trait and calling
-the `clone` method.
-
-*/
-
-use std::kinds::Freeze;
-
-/// A common trait for cloning an object.
-pub trait Clone {
- /// Returns a copy of the value. The contents of owned pointers
- /// are copied to maintain uniqueness, while the contents of
- /// managed pointers are not copied.
- fn clone(&self) -> Self;
-
- /// Perform copy-assignment from `source`.
- ///
- /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
- /// but can be overriden to reuse the resources of `a` to avoid unnecessary
- /// allocations.
- #[inline(always)]
- fn clone_from(&mut self, source: &Self) {
- *self = source.clone()
- }
-}
-
-impl<T: Clone> Clone for ~T {
- /// Return a copy of the owned box.
- #[inline]
- fn clone(&self) -> ~T { ~(**self).clone() }
-
- /// Perform copy-assignment from `source` by reusing the existing allocation.
- fn clone_from(&mut self, source: &~T) {
- **self = (**source).clone()
- }
-}
-
-impl<T> Clone for @T {
- /// Return a shallow copy of the managed box.
- #[inline]
- fn clone(&self) -> @T { *self }
-}
-
-impl<T> Clone for @mut T {
- /// Return a shallow copy of the managed box.
- #[inline]
- fn clone(&self) -> @mut T { *self }
-}
-
-impl<'self, T> Clone for &'self T {
- /// Return a shallow copy of the borrowed pointer.
- #[inline]
- fn clone(&self) -> &'self T { *self }
-}
-
-impl<'self, T> Clone for &'self [T] {
- /// Return a shallow copy of the slice.
- #[inline]
- fn clone(&self) -> &'self [T] { *self }
-}
-
-impl<'self> Clone for &'self str {
- /// Return a shallow copy of the slice.
- #[inline]
- fn clone(&self) -> &'self str { *self }
-}
-
-macro_rules! clone_impl(
- ($t:ty) => {
- impl Clone for $t {
- /// Return a deep copy of the value.
- #[inline]
- fn clone(&self) -> $t { *self }
- }
- }
-)
-
-clone_impl!(int)
-clone_impl!(i8)
-clone_impl!(i16)
-clone_impl!(i32)
-clone_impl!(i64)
-
-clone_impl!(uint)
-clone_impl!(u8)
-clone_impl!(u16)
-clone_impl!(u32)
-clone_impl!(u64)
-
-clone_impl!(f32)
-clone_impl!(f64)
-
-clone_impl!(())
-clone_impl!(bool)
-clone_impl!(char)
-
-macro_rules! extern_fn_clone(
- ($($A:ident),*) => (
- impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
- /// Return a copy of a function pointer
- #[inline]
- fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
- }
- )
-)
-
-extern_fn_clone!()
-extern_fn_clone!(A)
-extern_fn_clone!(A, B)
-extern_fn_clone!(A, B, C)
-extern_fn_clone!(A, B, C, D)
-extern_fn_clone!(A, B, C, D, E)
-extern_fn_clone!(A, B, C, D, E, F)
-extern_fn_clone!(A, B, C, D, E, F, G)
-extern_fn_clone!(A, B, C, D, E, F, G, H)
-
-/// A trait distinct from `Clone` which represents "deep copies" of things like
-/// managed boxes which would otherwise not be copied.
-pub trait DeepClone: Clone {
- /// Return a deep copy of the value. Unlike `Clone`, the contents of shared pointer types
- /// *are* copied.
- fn deep_clone(&self) -> Self;
-
- /// Perform deep copy-assignment from `source`.
- ///
- /// `a.deep_clone_from(&b)` is equivalent to `a = b.deep_clone()` in
- /// functionality, but can be overriden to reuse the resources of `a` to
- /// avoid unnecessary allocations.
- #[inline(always)]
- fn deep_clone_from(&mut self, source: &Self) {
- *self = source.deep_clone()
- }
-}
-
-impl<T: DeepClone> DeepClone for ~T {
- /// Return a deep copy of the owned box.
- #[inline]
- fn deep_clone(&self) -> ~T { ~(**self).deep_clone() }
-
- /// Perform deep copy-assignment from `source` by reusing the existing allocation.
- fn deep_clone_from(&mut self, source: &~T) {
- **self = (**source).deep_clone()
- }
-}
-
-// FIXME: #6525: should also be implemented for `T: Send + DeepClone`
-impl<T: Freeze + DeepClone + 'static> DeepClone for @T {
- /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing
- /// a deep clone of a potentially cyclical type.
- #[inline]
- fn deep_clone(&self) -> @T { @(**self).deep_clone() }
-}
-
-// FIXME: #6525: should also be implemented for `T: Send + DeepClone`
-impl<T: Freeze + DeepClone + 'static> DeepClone for @mut T {
- /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing
- /// a deep clone of a potentially cyclical type.
- #[inline]
- fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() }
-}
-
-macro_rules! deep_clone_impl(
- ($t:ty) => {
- impl DeepClone for $t {
- /// Return a deep copy of the value.
- #[inline]
- fn deep_clone(&self) -> $t { *self }
- }
- }
-)
-
-deep_clone_impl!(int)
-deep_clone_impl!(i8)
-deep_clone_impl!(i16)
-deep_clone_impl!(i32)
-deep_clone_impl!(i64)
-
-deep_clone_impl!(uint)
-deep_clone_impl!(u8)
-deep_clone_impl!(u16)
-deep_clone_impl!(u32)
-deep_clone_impl!(u64)
-
-deep_clone_impl!(f32)
-deep_clone_impl!(f64)
-
-deep_clone_impl!(())
-deep_clone_impl!(bool)
-deep_clone_impl!(char)
-
-macro_rules! extern_fn_deep_clone(
- ($($A:ident),*) => (
- impl<$($A,)* ReturnType> DeepClone for extern "Rust" fn($($A),*) -> ReturnType {
- /// Return a copy of a function pointer
- #[inline]
- fn deep_clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
- }
- )
-)
-
-extern_fn_deep_clone!()
-extern_fn_deep_clone!(A)
-extern_fn_deep_clone!(A, B)
-extern_fn_deep_clone!(A, B, C)
-extern_fn_deep_clone!(A, B, C, D)
-extern_fn_deep_clone!(A, B, C, D, E)
-extern_fn_deep_clone!(A, B, C, D, E, F)
-extern_fn_deep_clone!(A, B, C, D, E, F, G)
-extern_fn_deep_clone!(A, B, C, D, E, F, G, H)
-
-#[test]
-fn test_owned_clone() {
- let a = ~5i;
- let b: ~int = a.clone();
- assert_eq!(a, b);
-}
-
-#[test]
-fn test_managed_clone() {
- let a = @5i;
- let b: @int = a.clone();
- assert_eq!(a, b);
-}
-
-#[test]
-fn test_managed_mut_deep_clone() {
- let x = @mut 5i;
- let y: @mut int = x.deep_clone();
- *x = 20;
- assert_eq!(*y, 5);
-}
-
-#[test]
-fn test_managed_mut_clone() {
- let a = @mut 5i;
- let b: @mut int = a.clone();
- assert_eq!(a, b);
- *b = 10;
- assert_eq!(a, b);
-}
-
-#[test]
-fn test_borrowed_clone() {
- let x = 5i;
- let y: &int = &x;
- let z: &int = (&y).clone();
- assert_eq!(*z, 5);
-}
-
-#[test]
-fn test_clone_from() {
- let a = ~5;
- let mut b = ~10;
- b.clone_from(&a);
- assert_eq!(*b, 5);
-}
-
-#[test]
-fn test_deep_clone_from() {
- let a = ~5;
- let mut b = ~10;
- b.deep_clone_from(&a);
- assert_eq!(*b, 5);
-}
-
-#[test]
-fn test_extern_fn_clone() {
- trait Empty {}
- impl Empty for int {}
-
- fn test_fn_a() -> f64 { 1.0 }
- fn test_fn_b<T: Empty>(x: T) -> T { x }
- fn test_fn_c(_: int, _: f64, _: ~[int], _: int, _: int, _: int) {}
-
- let _ = test_fn_a.clone();
- let _ = test_fn_b::<int>.clone();
- let _ = test_fn_c.clone();
-
- let _ = test_fn_a.deep_clone();
- let _ = test_fn_b::<int>.deep_clone();
- let _ = test_fn_c.deep_clone();
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-The `Ord` and `Eq` comparison traits
-
-This module contains the definition of both `Ord` and `Eq` which define
-the common interfaces for doing comparison. Both are language items
-that the compiler uses to implement the comparison operators. Rust code
-may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
-and `Eq` to overload the `==` and `!=` operators.
-
-*/
-
-#[allow(missing_doc)];
-
-/**
-* Trait for values that can be compared for equality and inequality.
-*
-* This trait allows partial equality, where types can be unordered instead of strictly equal or
-* unequal. For example, with the built-in floating-point types `a == b` and `a != b` will both
-* evaluate to false if either `a` or `b` is NaN (cf. IEEE 754-2008 section 5.11).
-*
-* Eq only requires the `eq` method to be implemented; `ne` is its negation by default.
-*
-* Eventually, this will be implemented by default for types that implement `TotalEq`.
-*/
-#[lang="eq"]
-pub trait Eq {
- fn eq(&self, other: &Self) -> bool;
-
- #[inline]
- fn ne(&self, other: &Self) -> bool { !self.eq(other) }
-}
-
-/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses.
-pub trait TotalEq {
- fn equals(&self, other: &Self) -> bool;
-}
-
-macro_rules! totaleq_impl(
- ($t:ty) => {
- impl TotalEq for $t {
- #[inline]
- fn equals(&self, other: &$t) -> bool { *self == *other }
- }
- }
-)
-
-totaleq_impl!(bool)
-
-totaleq_impl!(u8)
-totaleq_impl!(u16)
-totaleq_impl!(u32)
-totaleq_impl!(u64)
-
-totaleq_impl!(i8)
-totaleq_impl!(i16)
-totaleq_impl!(i32)
-totaleq_impl!(i64)
-
-totaleq_impl!(int)
-totaleq_impl!(uint)
-
-totaleq_impl!(char)
-
-/// Trait for testing approximate equality
-pub trait ApproxEq<Eps> {
- fn approx_epsilon() -> Eps;
- fn approx_eq(&self, other: &Self) -> bool;
- fn approx_eq_eps(&self, other: &Self, approx_epsilon: &Eps) -> bool;
-}
-
-#[deriving(Clone, Eq)]
-pub enum Ordering { Less = -1, Equal = 0, Greater = 1 }
-
-/// Trait for types that form a total order
-pub trait TotalOrd: TotalEq {
- fn cmp(&self, other: &Self) -> Ordering;
-}
-
-impl TotalEq for Ordering {
- #[inline]
- fn equals(&self, other: &Ordering) -> bool {
- *self == *other
- }
-}
-impl TotalOrd for Ordering {
- #[inline]
- fn cmp(&self, other: &Ordering) -> Ordering {
- (*self as int).cmp(&(*other as int))
- }
-}
-
-impl Ord for Ordering {
- #[inline]
- fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
-}
-
-macro_rules! totalord_impl(
- ($t:ty) => {
- impl TotalOrd for $t {
- #[inline]
- fn cmp(&self, other: &$t) -> Ordering {
- if *self < *other { Less }
- else if *self > *other { Greater }
- else { Equal }
- }
- }
- }
-)
-
-totalord_impl!(u8)
-totalord_impl!(u16)
-totalord_impl!(u32)
-totalord_impl!(u64)
-
-totalord_impl!(i8)
-totalord_impl!(i16)
-totalord_impl!(i32)
-totalord_impl!(i64)
-
-totalord_impl!(int)
-totalord_impl!(uint)
-
-totalord_impl!(char)
-
-/// Compares (a1, b1) against (a2, b2), where the a values are more significant.
-pub fn cmp2<A:TotalOrd,B:TotalOrd>(
- a1: &A, b1: &B,
- a2: &A, b2: &B) -> Ordering
-{
- match a1.cmp(a2) {
- Less => Less,
- Greater => Greater,
- Equal => b1.cmp(b2)
- }
-}
-
-/**
-Return `o1` if it is not `Equal`, otherwise `o2`. Simulates the
-lexical ordering on a type `(int, int)`.
-*/
-#[inline]
-pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
- match o1 {
- Equal => o2,
- _ => o1
- }
-}
-
-/**
-* Trait for values that can be compared for a sort-order.
-*
-* Ord only requires implementation of the `lt` method,
-* with the others generated from default implementations.
-*
-* However it remains possible to implement the others separately,
-* for compatibility with floating-point NaN semantics
-* (cf. IEEE 754-2008 section 5.11).
-*/
-#[lang="ord"]
-pub trait Ord {
- fn lt(&self, other: &Self) -> bool;
- #[inline]
- fn le(&self, other: &Self) -> bool { !other.lt(self) }
- #[inline]
- fn gt(&self, other: &Self) -> bool { other.lt(self) }
- #[inline]
- fn ge(&self, other: &Self) -> bool { !self.lt(other) }
-}
-
-/// The equivalence relation. Two values may be equivalent even if they are
-/// of different types. The most common use case for this relation is
-/// container types; e.g. it is often desirable to be able to use `&str`
-/// values to look up entries in a container with `~str` keys.
-pub trait Equiv<T> {
- fn equiv(&self, other: &T) -> bool;
-}
-
-#[inline]
-pub fn min<T:Ord>(v1: T, v2: T) -> T {
- if v1 < v2 { v1 } else { v2 }
-}
-
-#[inline]
-pub fn max<T:Ord>(v1: T, v2: T) -> T {
- if v1 > v2 { v1 } else { v2 }
-}
-
-#[cfg(test)]
-mod test {
- use super::lexical_ordering;
-
- #[test]
- fn test_int_totalord() {
- assert_eq!(5.cmp(&10), Less);
- assert_eq!(10.cmp(&5), Greater);
- assert_eq!(5.cmp(&5), Equal);
- assert_eq!((-5).cmp(&12), Less);
- assert_eq!(12.cmp(-5), Greater);
- }
-
- #[test]
- fn test_cmp2() {
- assert_eq!(cmp2(1, 2, 3, 4), Less);
- assert_eq!(cmp2(3, 2, 3, 4), Less);
- assert_eq!(cmp2(5, 2, 3, 4), Greater);
- assert_eq!(cmp2(5, 5, 5, 4), Greater);
- }
-
- #[test]
- fn test_int_totaleq() {
- assert!(5.equals(&5));
- assert!(!2.equals(&17));
- }
-
- #[test]
- fn test_ordering_order() {
- assert!(Less < Equal);
- assert_eq!(Greater.cmp(&Less), Greater);
- }
-
- #[test]
- fn test_lexical_ordering() {
- fn t(o1: Ordering, o2: Ordering, e: Ordering) {
- assert_eq!(lexical_ordering(o1, o2), e);
- }
-
- let xs = [Less, Equal, Greater];
- for &o in xs.iter() {
- t(Less, o, Less);
- t(Equal, o, o);
- t(Greater, o, Greater);
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Message passing
-*/
-
-#[allow(missing_doc)];
-
-use clone::Clone;
-use iter::Iterator;
-use kinds::Send;
-use option::Option;
-use rtcomm = rt::comm;
-
-/// A trait for things that can send multiple messages.
-pub trait GenericChan<T> {
- /// Sends a message.
- fn send(&self, x: T);
-}
-
-/// Things that can send multiple messages and can detect when the receiver
-/// is closed
-pub trait GenericSmartChan<T> {
- /// Sends a message, or report if the receiver has closed the connection.
- fn try_send(&self, x: T) -> bool;
-}
-
-/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
-pub trait SendDeferred<T> {
- fn send_deferred(&self, val: T);
- fn try_send_deferred(&self, val: T) -> bool;
-}
-
-/// A trait for things that can receive multiple messages.
-pub trait GenericPort<T> {
- /// Receives a message, or fails if the connection closes.
- fn recv(&self) -> T;
-
- /// Receives a message, or returns `none` if
- /// the connection is closed or closes.
- fn try_recv(&self) -> Option<T>;
-
- /// Returns an iterator that breaks once the connection closes.
- ///
- /// # Example
- ///
- /// ~~~rust
- /// do spawn {
- /// for x in port.recv_iter() {
- /// if pred(x) { break; }
- /// println!("{}", x);
- /// }
- /// }
- /// ~~~
- fn recv_iter<'a>(&'a self) -> RecvIterator<'a, Self> {
- RecvIterator { port: self }
- }
-}
-
-pub struct RecvIterator<'a, P> {
- priv port: &'a P,
-}
-
-impl<'a, T, P: GenericPort<T>> Iterator<T> for RecvIterator<'a, P> {
- fn next(&mut self) -> Option<T> {
- self.port.try_recv()
- }
-}
-
-/// Ports that can `peek`
-pub trait Peekable<T> {
- /// Returns true if a message is available
- fn peek(&self) -> bool;
-}
-
-pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
-pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }
-
-pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
- let (p, c) = rtcomm::oneshot();
- (PortOne { x: p }, ChanOne { x: c })
-}
-
-pub struct Port<T> { priv x: rtcomm::Port<T> }
-pub struct Chan<T> { priv x: rtcomm::Chan<T> }
-
-pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
- let (p, c) = rtcomm::stream();
- (Port { x: p }, Chan { x: c })
-}
-
-impl<T: Send> ChanOne<T> {
- pub fn send(self, val: T) {
- let ChanOne { x: c } = self;
- c.send(val)
- }
-
- pub fn try_send(self, val: T) -> bool {
- let ChanOne { x: c } = self;
- c.try_send(val)
- }
-
- pub fn send_deferred(self, val: T) {
- let ChanOne { x: c } = self;
- c.send_deferred(val)
- }
-
- pub fn try_send_deferred(self, val: T) -> bool {
- let ChanOne{ x: c } = self;
- c.try_send_deferred(val)
- }
-}
-
-impl<T: Send> PortOne<T> {
- pub fn recv(self) -> T {
- let PortOne { x: p } = self;
- p.recv()
- }
-
- pub fn try_recv(self) -> Option<T> {
- let PortOne { x: p } = self;
- p.try_recv()
- }
-}
-
-impl<T: Send> Peekable<T> for PortOne<T> {
- fn peek(&self) -> bool {
- let &PortOne { x: ref p } = self;
- p.peek()
- }
-}
-
-impl<T: Send> GenericChan<T> for Chan<T> {
- fn send(&self, val: T) {
- let &Chan { x: ref c } = self;
- c.send(val)
- }
-}
-
-impl<T: Send> GenericSmartChan<T> for Chan<T> {
- fn try_send(&self, val: T) -> bool {
- let &Chan { x: ref c } = self;
- c.try_send(val)
- }
-}
-
-impl<T: Send> SendDeferred<T> for Chan<T> {
- fn send_deferred(&self, val: T) {
- let &Chan { x: ref c } = self;
- c.send_deferred(val)
- }
-
- fn try_send_deferred(&self, val: T) -> bool {
- let &Chan { x: ref c } = self;
- c.try_send_deferred(val)
- }
-}
-
-impl<T: Send> GenericPort<T> for Port<T> {
- fn recv(&self) -> T {
- let &Port { x: ref p } = self;
- p.recv()
- }
-
- fn try_recv(&self) -> Option<T> {
- let &Port { x: ref p } = self;
- p.try_recv()
- }
-}
-
-impl<T: Send> Peekable<T> for Port<T> {
- fn peek(&self) -> bool {
- let &Port { x: ref p } = self;
- p.peek()
- }
-}
-
-
-pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }
-
-impl<T: Send> SharedChan<T> {
- pub fn new(c: Chan<T>) -> SharedChan<T> {
- let Chan { x: c } = c;
- SharedChan { x: rtcomm::SharedChan::new(c) }
- }
-}
-
-impl<T: Send> GenericChan<T> for SharedChan<T> {
- fn send(&self, val: T) {
- let &SharedChan { x: ref c } = self;
- c.send(val)
- }
-}
-
-impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
- fn try_send(&self, val: T) -> bool {
- let &SharedChan { x: ref c } = self;
- c.try_send(val)
- }
-}
-
-impl<T: Send> SendDeferred<T> for SharedChan<T> {
- fn send_deferred(&self, val: T) {
- let &SharedChan { x: ref c } = self;
- c.send_deferred(val)
- }
-
- fn try_send_deferred(&self, val: T) -> bool {
- let &SharedChan { x: ref c } = self;
- c.try_send_deferred(val)
- }
-}
-
-impl<T: Send> Clone for SharedChan<T> {
- fn clone(&self) -> SharedChan<T> {
- let &SharedChan { x: ref c } = self;
- SharedChan { x: c.clone() }
- }
-}
-
-pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }
-
-impl<T: Send> SharedPort<T> {
- pub fn new(p: Port<T>) -> SharedPort<T> {
- let Port { x: p } = p;
- SharedPort { x: rtcomm::SharedPort::new(p) }
- }
-}
-
-impl<T: Send> GenericPort<T> for SharedPort<T> {
- fn recv(&self) -> T {
- let &SharedPort { x: ref p } = self;
- p.recv()
- }
-
- fn try_recv(&self) -> Option<T> {
- let &SharedPort { x: ref p } = self;
- p.try_recv()
- }
-}
-
-impl<T: Send> Clone for SharedPort<T> {
- fn clone(&self) -> SharedPort<T> {
- let &SharedPort { x: ref p } = self;
- SharedPort { x: p.clone() }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use comm::*;
- use prelude::*;
-
- #[test]
- fn test_nested_recv_iter() {
- let (port, chan) = stream::<int>();
- let (total_port, total_chan) = oneshot::<int>();
-
- do spawn {
- let mut acc = 0;
- for x in port.recv_iter() {
- acc += x;
- for x in port.recv_iter() {
- acc += x;
- for x in port.try_recv().move_iter() {
- acc += x;
- total_chan.send(acc);
- }
- }
- }
- }
-
- chan.send(3);
- chan.send(1);
- chan.send(2);
- assert_eq!(total_port.recv(), 6);
- }
-
- #[test]
- fn test_recv_iter_break() {
- let (port, chan) = stream::<int>();
- let (count_port, count_chan) = oneshot::<int>();
-
- do spawn {
- let mut count = 0;
- for x in port.recv_iter() {
- if count >= 3 {
- count_chan.send(count);
- break;
- } else {
- count += x;
- }
- }
- }
-
- chan.send(2);
- chan.send(2);
- chan.send(2);
- chan.send(2);
- assert_eq!(count_port.recv(), 4);
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Condition handling
-
-Conditions are a utility used to deal with handling error conditions. The syntax
-of a condition handler strikes a resemblance to try/catch blocks in other
-languages, but condition handlers are *not* a form of exception handling in the
-same manner.
-
-A condition is declared through the `condition!` macro provided by the compiler:
-
-```rust
-condition! {
- pub my_error: int -> ~str;
-}
- ```
-
-This macro declares an inner module called `my_error` with one static variable,
-`cond` that is a static `Condition` instance. To help understand what the other
-parameters are used for, an example usage of this condition would be:
-
-```rust
-my_error::cond.trap(|raised_int| {
-
- // the condition `my_error` was raised on, and the value it raised is stored
- // in `raised_int`. This closure must return a `~str` type (as specified in
- // the declaration of the condition
- if raised_int == 3 { ~"three" } else { ~"oh well" }
-
-}).inside(|| {
-
- // The condition handler above is installed for the duration of this block.
- // That handler will override any previous handler, but the previous handler
- // is restored when this block returns (handlers nest)
- //
- // If any code from this block (or code from another block) raises on the
- // condition, then the above handler will be invoked (so long as there's no
- // other nested handler).
-
- println(my_error::cond.raise(3)); // prints "three"
- println(my_error::cond.raise(4)); // prints "oh well"
-
-})
- ```
-
-Condition handling is useful in cases where propagating errors is either to
-cumbersome or just not necessary in the first place. It should also be noted,
-though, that if there is not handler installed when a condition is raised, then
-the task invokes `fail!()` and will terminate.
-
-## More Info
-
-Condition handlers as an error strategy is well explained in the [conditions
-tutorial](http://static.rust-lang.org/doc/master/tutorial-conditions.html),
-along with comparing and contrasting it with other error handling strategies.
-
-*/
-
-use local_data;
-use prelude::*;
-use unstable::raw::Closure;
-
-#[doc(hidden)]
-pub struct Handler<T, U> {
- priv handle: Closure,
- priv prev: Option<@Handler<T, U>>,
-}
-
-/// This struct represents the state of a condition handler. It contains a key
-/// into TLS which holds the currently install handler, along with the name of
-/// the condition (useful for debugging).
-///
-/// This struct should never be created directly, but rather only through the
-/// `condition!` macro provided to all libraries using libstd.
-pub struct Condition<T, U> {
- /// Name of the condition handler
- name: &'static str,
- /// TLS key used to insert/remove values in TLS.
- key: local_data::Key<@Handler<T, U>>
-}
-
-impl<T, U> Condition<T, U> {
- /// Creates an object which binds the specified handler. This will also save
- /// the current handler *on creation* such that when the `Trap` is consumed,
- /// it knows which handler to restore.
- ///
- /// # Example
- ///
- /// ```rust
- /// condition! { my_error: int -> int; }
- ///
- /// let trap = my_error::cond.trap(|error| error + 3);
- ///
- /// // use `trap`'s inside method to register the handler and then run a
- /// // block of code with the handler registered
- /// ```
- pub fn trap<'a>(&'a self, h: 'a |T| -> U) -> Trap<'a, T, U> {
- let h: Closure = unsafe { ::cast::transmute(h) };
- let prev = local_data::get(self.key, |k| k.map(|x| *x));
- let h = @Handler { handle: h, prev: prev };
- Trap { cond: self, handler: h }
- }
-
- /// Raises on this condition, invoking any handler if one has been
- /// registered, or failing the current task otherwise.
- ///
- /// While a condition handler is being run, the condition will have no
- /// handler listed, so a task failure will occur if the condition is
- /// re-raised during the handler.
- ///
- /// # Arguments
- ///
- /// * t - The argument to pass along to the condition handler.
- ///
- /// # Return value
- ///
- /// If a handler is found, its return value is returned, otherwise this
- /// function will not return.
- pub fn raise(&self, t: T) -> U {
- let msg = format!("Unhandled condition: {}: {:?}", self.name, t);
- self.raise_default(t, || fail!("{}", msg.clone()))
- }
-
- /// Performs the same functionality as `raise`, except that when no handler
- /// is found the `default` argument is called instead of failing the task.
- pub fn raise_default(&self, t: T, default: || -> U) -> U {
- match local_data::pop(self.key) {
- None => {
- debug!("Condition.raise: found no handler");
- default()
- }
- Some(handler) => {
- debug!("Condition.raise: found handler");
- match handler.prev {
- None => {}
- Some(hp) => local_data::set(self.key, hp)
- }
- let handle : |T| -> U = unsafe {
- ::cast::transmute(handler.handle)
- };
- let u = handle(t);
- local_data::set(self.key, handler);
- u
- }
- }
- }
-}
-
-/// A `Trap` is created when the `trap` method is invoked on a `Condition`, and
-/// it is used to actually bind a handler into the TLS slot reserved for this
-/// condition.
-///
-/// Normally this object is not dealt with directly, but rather it's directly
-/// used after being returned from `trap`
-struct Trap<'self, T, U> {
- priv cond: &'self Condition<T, U>,
- priv handler: @Handler<T, U>
-}
-
-impl<'self, T, U> Trap<'self, T, U> {
- /// Execute a block of code with this trap handler's exception handler
- /// registered.
- ///
- /// # Example
- ///
- /// ```rust
- /// condition! { my_error: int -> int; }
- ///
- /// let result = my_error::cond.trap(|error| error + 3).inside(|| {
- /// my_error::cond.raise(4)
- /// });
- /// assert_eq!(result, 7);
- /// ```
- pub fn inside<V>(&self, inner: 'self || -> V) -> V {
- let _g = Guard { cond: self.cond };
- debug!("Trap: pushing handler to TLS");
- local_data::set(self.cond.key, self.handler);
- inner()
- }
-}
-
-#[doc(hidden)]
-struct Guard<'self, T, U> {
- priv cond: &'self Condition<T, U>
-}
-
-#[unsafe_destructor]
-impl<'self, T, U> Drop for Guard<'self, T, U> {
- fn drop(&mut self) {
- debug!("Guard: popping handler from TLS");
- let curr = local_data::pop(self.cond.key);
- match curr {
- None => {}
- Some(h) => match h.prev {
- None => {}
- Some(hp) => local_data::set(self.cond.key, hp)
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- condition! {
- sadness: int -> int;
- }
-
- fn trouble(i: int) {
- debug!("trouble: raising condition");
- let j = sadness::cond.raise(i);
- debug!("trouble: handler recovered with {}", j);
- }
-
- fn nested_trap_test_inner() {
- let mut inner_trapped = false;
-
- sadness::cond.trap(|_j| {
- debug!("nested_trap_test_inner: in handler");
- inner_trapped = true;
- 0
- }).inside(|| {
- debug!("nested_trap_test_inner: in protected block");
- trouble(1);
- });
-
- assert!(inner_trapped);
- }
-
- #[test]
- fn nested_trap_test_outer() {
- let mut outer_trapped = false;
-
- sadness::cond.trap(|_j| {
- debug!("nested_trap_test_outer: in handler");
- outer_trapped = true; 0
- }).inside(|| {
- debug!("nested_guard_test_outer: in protected block");
- nested_trap_test_inner();
- trouble(1);
- });
-
- assert!(outer_trapped);
- }
-
- fn nested_reraise_trap_test_inner() {
- let mut inner_trapped = false;
-
- sadness::cond.trap(|_j| {
- debug!("nested_reraise_trap_test_inner: in handler");
- inner_trapped = true;
- let i = 10;
- debug!("nested_reraise_trap_test_inner: handler re-raising");
- sadness::cond.raise(i)
- }).inside(|| {
- debug!("nested_reraise_trap_test_inner: in protected block");
- trouble(1);
- });
-
- assert!(inner_trapped);
- }
-
- #[test]
- fn nested_reraise_trap_test_outer() {
- let mut outer_trapped = false;
-
- sadness::cond.trap(|_j| {
- debug!("nested_reraise_trap_test_outer: in handler");
- outer_trapped = true; 0
- }).inside(|| {
- debug!("nested_reraise_trap_test_outer: in protected block");
- nested_reraise_trap_test_inner();
- });
-
- assert!(outer_trapped);
- }
-
- #[test]
- fn test_default() {
- let mut trapped = false;
-
- sadness::cond.trap(|j| {
- debug!("test_default: in handler");
- sadness::cond.raise_default(j, || { trapped=true; 5 })
- }).inside(|| {
- debug!("test_default: in protected block");
- trouble(1);
- });
-
- assert!(trapped);
- }
-
- // Issue #6009
- mod m {
- condition! {
- // #6009, #8215: should this truly need a `pub` for access from n?
- pub sadness: int -> int;
- }
-
- mod n {
- use super::sadness;
-
- #[test]
- fn test_conditions_are_public() {
- let mut trapped = false;
- sadness::cond.trap(|_| {
- trapped = true;
- 0
- }).inside(|| {
- sadness::cond.raise(0);
- });
- assert!(trapped);
- }
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Container traits
-
-use option::Option;
-
-/// A trait to represent the abstract idea of a container. The only concrete
-/// knowledge known is the number of elements contained within.
-pub trait Container {
- /// Return the number of elements in the container
- fn len(&self) -> uint;
-
- /// Return true if the container contains no elements
- #[inline]
- fn is_empty(&self) -> bool {
- self.len() == 0
- }
-}
-
-/// A trait to represent mutable containers
-pub trait Mutable: Container {
- /// Clear the container, removing all values.
- fn clear(&mut self);
-}
-
-/// A map is a key-value store where values may be looked up by their keys. This
-/// trait provides basic operations to operate on these stores.
-pub trait Map<K, V>: Container {
- /// Return a reference to the value corresponding to the key
- fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
-
- /// Return true if the map contains a value for the specified key
- #[inline]
- fn contains_key(&self, key: &K) -> bool {
- self.find(key).is_some()
- }
-}
-
-/// This trait provides basic operations to modify the contents of a map.
-pub trait MutableMap<K, V>: Map<K, V> + Mutable {
- /// Insert a key-value pair into the map. An existing value for a
- /// key is replaced by the new value. Return true if the key did
- /// not already exist in the map.
- #[inline]
- fn insert(&mut self, key: K, value: V) -> bool {
- self.swap(key, value).is_none()
- }
-
- /// Remove a key-value pair from the map. Return true if the key
- /// was present in the map, otherwise false.
- #[inline]
- fn remove(&mut self, key: &K) -> bool {
- self.pop(key).is_some()
- }
-
- /// Insert a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise None is returned.
- fn swap(&mut self, k: K, v: V) -> Option<V>;
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- fn pop(&mut self, k: &K) -> Option<V>;
-
- /// Return a mutable reference to the value corresponding to the key
- fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
-}
-
-/// A set is a group of objects which are each distinct from one another. This
-/// trait represents actions which can be performed on sets to iterate over
-/// them.
-pub trait Set<T>: Container {
- /// Return true if the set contains a value
- fn contains(&self, value: &T) -> bool;
-
- /// Return true if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- fn is_disjoint(&self, other: &Self) -> bool;
-
- /// Return true if the set is a subset of another
- fn is_subset(&self, other: &Self) -> bool;
-
- /// Return true if the set is a superset of another
- fn is_superset(&self, other: &Self) -> bool;
-
- // FIXME #8154: Add difference, sym. difference, intersection and union iterators
-}
-
-/// This trait represents actions which can be performed on sets to mutate
-/// them.
-pub trait MutableSet<T>: Set<T> + Mutable {
- /// Add a value to the set. Return true if the value was not already
- /// present in the set.
- fn insert(&mut self, value: T) -> bool;
-
- /// Remove a value from the set. Return true if the value was
- /// present in the set.
- fn remove(&mut self, value: &T) -> bool;
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The Default trait
-
-/// A trait that types which have a useful default value should implement.
-pub trait Default {
- /// Return the "default value" for a type.
- fn default() -> Self;
-}
-
-impl<T: Default + 'static> Default for @mut T {
- fn default() -> @mut T { @mut Default::default() }
-}
-
-impl<T: Default + 'static> Default for @T {
- fn default() -> @T { @Default::default() }
-}
-
-impl<T: Default> Default for ~T {
- fn default() -> ~T { ~Default::default() }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A type that represents one of two alternatives
-
-#[allow(missing_doc)];
-
-use option::{Some, None};
-use option;
-use clone::Clone;
-use container::Container;
-use cmp::Eq;
-use iter::{Iterator, FilterMap};
-use result::Result;
-use result;
-use str::StrSlice;
-use vec;
-use vec::{OwnedVector, ImmutableVector};
-
-/// `Either` is a type that represents one of two alternatives
-#[deriving(Clone, Eq, IterBytes)]
-pub enum Either<L, R> {
- Left(L),
- Right(R)
-}
-
-impl<L, R> Either<L, R> {
- /// Applies a function based on the given either value
- ///
- /// If `value` is `Left(L)` then `f_left` is applied to its contents, if
- /// `value` is `Right(R)` then `f_right` is applied to its contents, and the
- /// result is returned.
- #[inline]
- pub fn either<T>(&self, f_left: |&L| -> T, f_right: |&R| -> T) -> T {
- match *self {
- Left(ref l) => f_left(l),
- Right(ref r) => f_right(r)
- }
- }
-
- /// Flips between left and right of a given `Either`
- #[inline]
- pub fn flip(self) -> Either<R, L> {
- match self {
- Right(r) => Left(r),
- Left(l) => Right(l)
- }
- }
-
- /// Checks whether the given value is a `Left`
- #[inline]
- pub fn is_left(&self) -> bool {
- match *self {
- Left(_) => true,
- _ => false
- }
- }
-
- /// Checks whether the given value is a `Right`
- #[inline]
- pub fn is_right(&self) -> bool {
- match *self {
- Right(_) => true,
- _ => false
- }
- }
-
- /// Retrieves the value from a `Left`.
- /// Fails with a specified reason if the `Either` is `Right`.
- #[inline]
- pub fn expect_left(self, reason: &str) -> L {
- match self {
- Left(x) => x,
- Right(_) => fail!("{}", reason.to_owned())
- }
- }
-
- /// Retrieves the value from a `Left`. Fails if the `Either` is `Right`.
- #[inline]
- pub fn unwrap_left(self) -> L {
- self.expect_left("called Either::unwrap_left()` on `Right` value")
- }
-
- /// Retrieves the value from a `Right`.
- /// Fails with a specified reason if the `Either` is `Left`.
- #[inline]
- pub fn expect_right(self, reason: &str) -> R {
- match self {
- Right(x) => x,
- Left(_) => fail!("{}", reason.to_owned())
- }
- }
-
- /// Retrieves the value from a `Right`. Fails if the `Either` is `Left`.
- #[inline]
- pub fn unwrap_right(self) -> R {
- self.expect_right("called Either::unwrap_right()` on `Left` value")
- }
-}
-
-/// A generic trait for converting a value to a `Either`
-pub trait ToEither<L, R> {
- /// Convert to the `either` type
- fn to_either(&self) -> Either<L, R>;
-}
-
-/// A generic trait for converting a value to a `Either`
-pub trait IntoEither<L, R> {
- /// Convert to the `either` type
- fn into_either(self) -> Either<L, R>;
-}
-
-/// A generic trait for converting a value to a `Either`
-pub trait AsEither<L, R> {
- /// Convert to the `either` type
- fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>;
-}
-
-impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
- #[inline]
- fn to_option(&self)-> option::Option<R> {
- match *self {
- Left(_) => None,
- Right(ref r) => Some(r.clone()),
- }
- }
-}
-
-impl<L, R> option::IntoOption<R> for Either<L, R> {
- #[inline]
- fn into_option(self)-> option::Option<R> {
- match self {
- Left(_) => None,
- Right(r) => Some(r),
- }
- }
-}
-
-impl<L, R> option::AsOption<R> for Either<L, R> {
- #[inline]
- fn as_option<'a>(&'a self) -> option::Option<&'a R> {
- match *self {
- Left(_) => None,
- Right(ref r) => Some(r),
- }
- }
-}
-
-impl<L: Clone, R: Clone> result::ToResult<R, L> for Either<L, R> {
- #[inline]
- fn to_result(&self)-> result::Result<R, L> {
- match *self {
- Left(ref l) => result::Err(l.clone()),
- Right(ref r) => result::Ok(r.clone()),
- }
- }
-}
-
-impl<L, R> result::IntoResult<R, L> for Either<L, R> {
- #[inline]
- fn into_result(self)-> result::Result<R, L> {
- match self {
- Left(l) => result::Err(l),
- Right(r) => result::Ok(r),
- }
- }
-}
-
-impl<L, R> result::AsResult<R, L> for Either<L, R> {
- #[inline]
- fn as_result<'a>(&'a self) -> result::Result<&'a R, &'a L> {
- match *self {
- Left(ref l) => result::Err(l),
- Right(ref r) => result::Ok(r),
- }
- }
-}
-
-impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
- fn to_either(&self) -> Either<L, R> { self.clone() }
-}
-
-impl<L, R> IntoEither<L, R> for Either<L, R> {
- fn into_either(self) -> Either<L, R> { self }
-}
-
-impl<L, R> AsEither<L, R> for Either<L, R> {
- fn as_either<'a>(&'a self) -> Either<&'a L, &'a R> {
- match *self {
- Left(ref l) => Left(l),
- Right(ref r) => Right(r),
- }
- }
-}
-
-/// An iterator yielding the `Left` values of its source
-pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
-
-/// An iterator yielding the `Right` values of its source
-pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
-
-/// Extracts all the left values
-pub fn lefts<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
- -> Lefts<L, R, Iter> {
- eithers.filter_map(|elt| {
- match elt {
- Left(x) => Some(x),
- _ => None,
- }
- })
-}
-
-/// Extracts all the right values
-pub fn rights<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
- -> Rights<L, R, Iter> {
- eithers.filter_map(|elt| {
- match elt {
- Right(x) => Some(x),
- _ => None,
- }
- })
-}
-
-
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the left values and right values
-///
-/// Returns a structure containing a vector of left values and a vector of
-/// right values.
-pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
- let n_lefts = eithers.iter().count(|elt| elt.is_left());
- let mut lefts = vec::with_capacity(n_lefts);
- let mut rights = vec::with_capacity(eithers.len() - n_lefts);
- for elt in eithers.move_iter() {
- match elt {
- Left(l) => lefts.push(l),
- Right(r) => rights.push(r)
- }
- }
- return (lefts, rights);
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use option::{IntoOption, ToOption, AsOption};
- use option;
- use result::{IntoResult, ToResult, AsResult};
- use result;
-
- #[test]
- fn test_either_left() {
- let val = Left(10);
- fn f_left(x: &int) -> bool { *x == 10 }
- fn f_right(_x: &uint) -> bool { false }
- assert!(val.either(f_left, f_right));
- }
-
- #[test]
- fn test_either_right() {
- let val = Right(10u);
- fn f_left(_x: &int) -> bool { false }
- fn f_right(x: &uint) -> bool { *x == 10u }
- assert!(val.either(f_left, f_right));
- }
-
- #[test]
- fn test_lefts() {
- let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
- let result = lefts(input.move_iter()).to_owned_vec();
- assert_eq!(result, ~[10, 12, 14]);
- }
-
- #[test]
- fn test_lefts_none() {
- let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
- let result = lefts(input.move_iter()).to_owned_vec();
- assert_eq!(result.len(), 0u);
- }
-
- #[test]
- fn test_lefts_empty() {
- let input: ~[Either<int, int>] = ~[];
- let result = lefts(input.move_iter()).to_owned_vec();
- assert_eq!(result.len(), 0u);
- }
-
- #[test]
- fn test_rights() {
- let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
- let result = rights(input.move_iter()).to_owned_vec();
- assert_eq!(result, ~[11, 13]);
- }
-
- #[test]
- fn test_rights_none() {
- let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
- let result = rights(input.move_iter()).to_owned_vec();
- assert_eq!(result.len(), 0u);
- }
-
- #[test]
- fn test_rights_empty() {
- let input: ~[Either<int, int>] = ~[];
- let result = rights(input.move_iter()).to_owned_vec();
- assert_eq!(result.len(), 0u);
- }
-
- #[test]
- fn test_partition() {
- let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
- let (lefts, rights) = partition(input);
- assert_eq!(lefts[0], 10);
- assert_eq!(lefts[1], 12);
- assert_eq!(lefts[2], 14);
- assert_eq!(rights[0], 11);
- assert_eq!(rights[1], 13);
- }
-
- #[test]
- fn test_partition_no_lefts() {
- let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
- let (lefts, rights) = partition(input);
- assert_eq!(lefts.len(), 0u);
- assert_eq!(rights.len(), 2u);
- }
-
- #[test]
- fn test_partition_no_rights() {
- let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
- let (lefts, rights) = partition(input);
- assert_eq!(lefts.len(), 2u);
- assert_eq!(rights.len(), 0u);
- }
-
- #[test]
- fn test_partition_empty() {
- let input: ~[Either<int, int>] = ~[];
- let (lefts, rights) = partition(input);
- assert_eq!(lefts.len(), 0u);
- assert_eq!(rights.len(), 0u);
- }
-
- #[test]
- pub fn test_to_option() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.to_option(), option::Some(100));
- assert_eq!(left.to_option(), option::None);
- }
-
- #[test]
- pub fn test_into_option() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.into_option(), option::Some(100));
- assert_eq!(left.into_option(), option::None);
- }
-
- #[test]
- pub fn test_as_option() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.as_option().unwrap(), &100);
- assert_eq!(left.as_option(), option::None);
- }
-
- #[test]
- pub fn test_to_result() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.to_result(), result::Ok(100));
- assert_eq!(left.to_result(), result::Err(404));
- }
-
- #[test]
- pub fn test_into_result() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.into_result(), result::Ok(100));
- assert_eq!(left.into_result(), result::Err(404));
- }
-
- #[test]
- pub fn test_as_result() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- let x = 100;
- assert_eq!(right.as_result(), result::Ok(&x));
-
- let x = 404;
- assert_eq!(left.as_result(), result::Err(&x));
- }
-
- #[test]
- pub fn test_to_either() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.to_either(), Right(100));
- assert_eq!(left.to_either(), Left(404));
- }
-
- #[test]
- pub fn test_into_either() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.into_either(), Right(100));
- assert_eq!(left.into_either(), Left(404));
- }
-
- #[test]
- pub fn test_as_either() {
- let right: Either<int, int> = Right(100);
- let left: Either<int, int> = Left(404);
-
- assert_eq!(right.as_either().unwrap_right(), &100);
- assert_eq!(left.as_either().unwrap_left(), &404);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-The Formatting Module
-
-This module contains the runtime support for the `format!` syntax extension.
-This macro is implemented in the compiler to emit calls to this module in order
-to format arguments at runtime into strings and streams.
-
-The functions contained in this module should not normally be used in everyday
-use cases of `format!`. The assumptions made by these functions are unsafe for
-all inputs, and the compiler performs a large amount of validation on the
-arguments to `format!` in order to ensure safety at runtime. While it is
-possible to call these functions directly, it is not recommended to do so in the
-general case.
-
-## Usage
-
-The `format!` macro is intended to be familiar to those coming from C's
-printf/fprintf functions or Python's `str.format` function. In its current
-revision, the `format!` macro returns a `~str` type which is the result of the
-formatting. In the future it will also be able to pass in a stream to format
-arguments directly while performing minimal allocations.
-
-Some examples of the `format!` extension are:
-
-```rust
-format!("Hello") // => ~"Hello"
-format!("Hello, {:s}!", "world") // => ~"Hello, world!"
-format!("The number is {:d}", 1) // => ~"The number is 1"
-format!("{:?}", ~[3, 4]) // => ~"~[3, 4]"
-format!("{value}", value=4) // => ~"4"
-format!("{} {}", 1, 2) // => ~"1 2"
-```
-
-From these, you can see that the first argument is a format string. It is
-required by the compiler for this to be a string literal; it cannot be a
-variable passed in (in order to perform validity checking). The compiler will
-then parse the format string and determine if the list of arguments provided is
-suitable to pass to this format string.
-
-### Positional parameters
-
-Each formatting argument is allowed to specify which value argument it's
-referencing, and if omitted it is assumed to be "the next argument". For
-example, the format string `{} {} {}` would take three parameters, and they
-would be formatted in the same order as they're given. The format string
-`{2} {1} {0}`, however, would format arguments in reverse order.
-
-Things can get a little tricky once you start intermingling the two types of
-positional specifiers. The "next argument" specifier can be thought of as an
-iterator over the argument. Each time a "next argument" specifier is seen, the
-iterator advances. This leads to behavior like this:
-
-```rust
-format!("{1} {} {0} {}", 1, 2) // => ~"2 1 1 2"
-```
-
-The internal iterator over the argument has not been advanced by the time the
-first `{}` is seen, so it prints the first argument. Then upon reaching the
-second `{}`, the iterator has advanced forward to the second argument.
-Essentially, parameters which explicitly name their argument do not affect
-parameters which do not name an argument in terms of positional specifiers.
-
-A format string is required to use all of its arguments, otherwise it is a
-compile-time error. You may refer to the same argument more than once in the
-format string, although it must always be referred to with the same type.
-
-### Named parameters
-
-Rust itself does not have a Python-like equivalent of named parameters to a
-function, but the `format!` macro is a syntax extension which allows it to
-leverage named parameters. Named parameters are listed at the end of the
-argument list and have the syntax:
-
-```
-identifier '=' expression
-```
-
-For example, the following `format!` expressions all use named argument:
-
-```rust
-format!("{argument}", argument = "test") // => ~"test"
-format!("{name} {}", 1, name = 2) // => ~"2 1"
-format!("{a:s} {c:d} {b:?}", a="a", b=(), c=3) // => ~"a 3 ()"
-```
-
-It is illegal to put positional parameters (those without names) after arguments
-which have names. Like positional parameters, it is illegal to provided named
-parameters that are unused by the format string.
-
-### Argument types
-
-Each argument's type is dictated by the format string. It is a requirement that
-every argument is only ever referred to by one type. When specifying the format
-of an argument, however, a string like `{}` indicates no type. This is allowed,
-and if all references to one argument do not provide a type, then the format `?`
-is used (the type's rust-representation is printed). For example, this is an
-invalid format string:
-
-```
-{0:d} {0:s}
-```
-
-Because the first argument is both referred to as an integer as well as a
-string.
-
-Because formatting is done via traits, there is no requirement that the
-`d` format actually takes an `int`, but rather it simply requires a type which
-ascribes to the `Signed` formatting trait. There are various parameters which do
-require a particular type, however. Namely if the syntax `{:.*s}` is used, then
-the number of characters to print from the string precedes the actual string and
-must have the type `uint`. Although a `uint` can be printed with `{:u}`, it is
-illegal to reference an argument as such. For example, this is another invalid
-format string:
-
-```
-{:.*s} {0:u}
-```
-
-### Formatting traits
-
-When requesting that an argument be formatted with a particular type, you are
-actually requesting that an argument ascribes to a particular trait. This allows
-multiple actual types to be formatted via `{:d}` (like `i8` as well as `int`).
-The current mapping of types to traits is:
-
-* `?` ⇒ `Poly`
-* `d` ⇒ `Signed`
-* `i` ⇒ `Signed`
-* `u` ⇒ `Unsigned`
-* `b` ⇒ `Bool`
-* `c` ⇒ `Char`
-* `o` ⇒ `Octal`
-* `x` ⇒ `LowerHex`
-* `X` ⇒ `UpperHex`
-* `s` ⇒ `String`
-* `p` ⇒ `Pointer`
-* `t` ⇒ `Binary`
-* `f` ⇒ `Float`
-* *nothing* ⇒ `Default`
-
-What this means is that any type of argument which implements the
-`std::fmt::Binary` trait can then be formatted with `{:t}`. Implementations are
-provided for these traits for a number of primitive types by the standard
-library as well. If no format is specified (as in `{}` or `{:6}`), then the
-format trait used is the `Default` trait. This is one of the more commonly
-implemented traits when formatting a custom type.
-
-When implementing a format trait for your own time, you will have to implement a
-method of the signature:
-
-```rust
-fn fmt(value: &T, f: &mut std::fmt::Formatter);
-```
-
-Your type will be passed by-reference in `value`, and then the function should
-emit output into the `f.buf` stream. It is up to each format trait
-implementation to correctly adhere to the requested formatting parameters. The
-values of these parameters will be listed in the fields of the `Formatter`
-struct. In order to help with this, the `Formatter` struct also provides some
-helper methods. An example of implementing the formatting traits would look
-like:
-
-```rust
-use std::fmt;
-use std::f64;
-
-struct Vector2D {
- x: int,
- y: int,
-}
-
-impl fmt::Default for Vector2D {
- fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
- // The `f.buf` value is of the type `&mut io::Writer`, which is what th
- // write! macro is expecting. Note that this formatting ignores the
- // various flags provided to format strings.
- write!(f.buf, "({}, {})", obj.x, obj.y)
- }
-}
-
-// Different traits allow different forms of output of a type. The meaning of
-// this format is to print the magnitude of a vector.
-impl fmt::Binary for Vector2D {
- fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
- let magnitude = (obj.x * obj.x + obj.y * obj.y) as f64;
- let magnitude = magnitude.sqrt();
-
- // Respect the formatting flags by using the helper method
- // `pad_integral` on the Formatter object. See the method documentation
- // for details, and the function `pad` can be used to pad strings.
- let decimals = f.precision.unwrap_or(3);
- let string = f64::to_str_exact(magnitude, decimals);
- f.pad_integral(string.as_bytes(), "", true);
- }
-}
-
-fn main() {
- let myvector = Vector2D { x: 3, y: 4 };
-
- println!("{}", myvector); // => "(3, 4)"
- println!("{:10.3t}", myvector); // => " 5.000"
-}
-```
-
-### Related macros
-
-There are a number of related macros in the `format!` family. The ones that are
-currently implemented are:
-
-```rust
-format! // described above
-write! // first argument is a &mut io::Writer, the destination
-writeln! // same as write but appends a newline
-print! // the format string is printed to the standard output
-println! // same as print but appends a newline
-format_args! // described below.
-```
-
-
-#### `write!`
-
-This and `writeln` are two macros which are used to emit the format string to a
-specified stream. This is used to prevent intermediate allocations of format
-strings and instead directly write the output. Under the hood, this function is
-actually invoking the `write` function defined in this module. Example usage is:
-
-```rust
-use std::io;
-
-let mut w = io::mem::MemWriter::new();
-write!(&mut w as &mut io::Writer, "Hello {}!", "world");
-```
-
-#### `print!`
-
-This and `println` emit their output to stdout. Similarly to the `write!` macro,
-the goal of these macros is to avoid intermediate allocations when printing
-output. Example usage is:
-
-```rust
-print!("Hello {}!", "world");
-println!("I have a newline {}", "character at the end");
-```
-
-#### `format_args!`
-This is a curious macro which is used to safely pass around
-an opaque object describing the format string. This object
-does not require any heap allocations to create, and it only
-references information on the stack. Under the hood, all of
-the related macros are implemented in terms of this. First
-off, some example usage is:
-
-```rust
-use std::fmt;
-
-format_args!(fmt::format, "this returns {}", "~str");
-format_args!(|args| { fmt::write(my_writer, args) }, "some {}", "args");
-format_args!(my_fn, "format {}", "string");
-```
-
-The first argument of the `format_args!` macro is a function (or closure) which
-takes one argument of type `&fmt::Arguments`. This structure can then be
-passed to the `write` and `format` functions inside this module in order to
-process the format string. The goal of this macro is to even further prevent
-intermediate allocations when dealing formatting strings.
-
-For example, a logging library could use the standard formatting syntax, but it
-would internally pass around this structure until it has been determined where
-output should go to.
-
-It is unsafe to programmatically create an instance of `fmt::Arguments` because
-the operations performed when executing a format string require the compile-time
-checks provided by the compiler. The `format_args!` macro is the only method of
-safely creating these structures, but they can be unsafely created with the
-constructor provided.
-
-## Internationalization
-
-The formatting syntax supported by the `format!` extension supports
-internationalization by providing "methods" which execute various different
-outputs depending on the input. The syntax and methods provided are similar to
-other internationalization systems, so again nothing should seem alien.
-Currently two methods are supported by this extension: "select" and "plural".
-
-Each method will execute one of a number of clauses, and then the value of the
-clause will become what's the result of the argument's format. Inside of the
-cases, nested argument strings may be provided, but all formatting arguments
-must not be done through implicit positional means. All arguments inside of each
-case of a method must be explicitly selected by their name or their integer
-position.
-
-Furthermore, whenever a case is running, the special character `#` can be used
-to reference the string value of the argument which was selected upon. As an
-example:
-
-```rust
-format!("{0, select, other{#}}", "hello") // => ~"hello"
-```
-
-This example is the equivalent of `{0:s}` essentially.
-
-### Select
-
-The select method is a switch over a `&str` parameter, and the parameter *must*
-be of the type `&str`. An example of the syntax is:
-
-```
-{0, select, male{...} female{...} other{...}}
-```
-
-Breaking this down, the `0`-th argument is selected upon with the `select`
-method, and then a number of cases follow. Each case is preceded by an
-identifier which is the match-clause to execute the given arm. In this case,
-there are two explicit cases, `male` and `female`. The case will be executed if
-the string argument provided is an exact match to the case selected.
-
-The `other` case is also a required case for all `select` methods. This arm will
-be executed if none of the other arms matched the word being selected over.
-
-### Plural
-
-The plural method is a switch statement over a `uint` parameter, and the
-parameter *must* be a `uint`. A plural method in its full glory can be specified
-as:
-
-```
-{0, plural, offset=1 =1{...} two{...} many{...} other{...}}
-```
-
-To break this down, the first `0` indicates that this method is selecting over
-the value of the first positional parameter to the format string. Next, the
-`plural` method is being executed. An optionally-supplied `offset` is then given
-which indicates a number to subtract from argument `0` when matching. This is
-then followed by a list of cases.
-
-Each case is allowed to supply a specific value to match upon with the syntax
-`=N`. This case is executed if the value at argument `0` matches N exactly,
-without taking the offset into account. A case may also be specified by one of
-five keywords: `zero`, `one`, `two`, `few`, and `many`. These cases are matched
-on after argument `0` has the offset taken into account. Currently the
-definitions of `many` and `few` are hardcoded, but they are in theory defined by
-the current locale.
-
-Finally, all `plural` methods must have an `other` case supplied which will be
-executed if none of the other cases match.
-
-## Syntax
-
-The syntax for the formatting language used is drawn from other languages, so it
-should not be too alien. Arguments are formatted with python-like syntax,
-meaning that arguments are surrounded by `{}` instead of the C-like `%`. The
-actual grammar for the formatting syntax is:
-
-```
-format_string := <text> [ format <text> ] *
-format := '{' [ argument ] [ ':' format_spec ] [ ',' function_spec ] '}'
-argument := integer | identifier
-
-format_spec := [[fill]align][sign]['#'][0][width]['.' precision][type]
-fill := character
-align := '<' | '>'
-sign := '+' | '-'
-width := count
-precision := count | '*'
-type := identifier | ''
-count := parameter | integer
-parameter := integer '$'
-
-function_spec := plural | select
-select := 'select' ',' ( identifier arm ) *
-plural := 'plural' ',' [ 'offset:' integer ] ( selector arm ) *
-selector := '=' integer | keyword
-keyword := 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'
-arm := '{' format_string '}'
-```
-
-## Formatting Parameters
-
-Each argument being formatted can be transformed by a number of formatting
-parameters (corresponding to `format_spec` in the syntax above). These
-parameters affect the string representation of what's being formatted. This
-syntax draws heavily from Python's, so it may seem a bit familiar.
-
-### Fill/Alignment
-
-The fill character is provided normally in conjunction with the `width`
-parameter. This indicates that if the value being formatted is smaller than
-`width` some extra characters will be printed around it. The extra characters
-are specified by `fill`, and the alignment can be one of two options:
-
-* `<` - the argument is left-aligned in `width` columns
-* `>` - the argument is right-aligned in `width` columns
-
-### Sign/#/0
-
-These can all be interpreted as flags for a particular formatter.
-
-* '+' - This is intended for numeric types and indicates that the sign should
- always be printed. Positive signs are never printed by default, and the
- negative sign is only printed by default for the `Signed` trait. This
- flag indicates that the correct sign (+ or -) should always be printed.
-* '-' - Currently not used
-* '#' - This flag is indicates that the "alternate" form of printing should be
- used. By default, this only applies to the integer formatting traits and
- performs like:
- * `x` - precedes the argument with a "0x"
- * `X` - precedes the argument with a "0x"
- * `t` - precedes the argument with a "0b"
- * `o` - precedes the argument with a "0o"
-* '0' - This is used to indicate for integer formats that the padding should
- both be done with a `0` character as well as be sign-aware. A format
- like `{:08d}` would yield `00000001` for the integer `1`, while the same
- format would yield `-0000001` for the integer `-1`. Notice that the
- negative version has one fewer zero than the positive version.
-
-### Width
-
-This is a parameter for the "minimum width" that the format should take up. If
-the value's string does not fill up this many characters, then the padding
-specified by fill/alignment will be used to take up the required space.
-
-The default fill/alignment for non-numerics is a space and left-aligned. The
-defaults for numeric formatters is also a space but with right-alignment. If the
-'0' flag is specified for numerics, then the implicit fill character is '0'.
-
-The value for the width can also be provided as a `uint` in the list of
-parameters by using the `2$` syntax indicating that the second argument is a
-`uint` specifying the width.
-
-### Precision
-
-For non-numeric types, this can be considered a "maximum width". If the
-resulting string is longer than this width, then it is truncated down to this
-many characters and only those are emitted.
-
-For integral types, this has no meaning currently.
-
-For floating-point types, this indicates how many digits after the decimal point
-should be printed.
-
-## Escaping
-
-The literal characters `{`, `}`, or `#` may be included in a string by
-preceding them with the `\` character. Since `\` is already an
-escape character in Rust strings, a string literal using this escape
-will look like `"\\{"`.
-
-*/
-
-use prelude::*;
-
-use cast;
-use char::Char;
-use io::Decorator;
-use io::mem::MemWriter;
-use io;
-use str;
-use repr;
-use util;
-use vec;
-
-pub mod parse;
-pub mod rt;
-
-/// A struct to represent both where to emit formatting strings to and how they
-/// should be formatted. A mutable version of this is passed to all formatting
-/// traits.
-pub struct Formatter<'self> {
- /// Flags for formatting (packed version of rt::Flag)
- flags: uint,
- /// Character used as 'fill' whenever there is alignment
- fill: char,
- /// Boolean indication of whether the output should be left-aligned
- align: parse::Alignment,
- /// Optionally specified integer width that the output should be
- width: Option<uint>,
- /// Optionally specified precision for numeric types
- precision: Option<uint>,
-
- /// Output buffer.
- buf: &'self mut io::Writer,
- priv curarg: vec::VecIterator<'self, Argument<'self>>,
- priv args: &'self [Argument<'self>],
-}
-
-/// This struct represents the generic "argument" which is taken by the Xprintf
-/// family of functions. It contains a function to format the given value. At
-/// compile time it is ensured that the function and the value have the correct
-/// types, and then this struct is used to canonicalize arguments to one type.
-pub struct Argument<'self> {
- priv formatter: extern "Rust" fn(&util::Void, &mut Formatter),
- priv value: &'self util::Void,
-}
-
-impl<'self> Arguments<'self> {
- /// When using the format_args!() macro, this function is used to generate the
- /// Arguments structure. The compiler inserts an `unsafe` block to call this,
- /// which is valid because the compiler performs all necessary validation to
- /// ensure that the resulting call to format/write would be safe.
- #[doc(hidden)] #[inline]
- pub unsafe fn new<'a>(fmt: &'static [rt::Piece<'static>],
- args: &'a [Argument<'a>]) -> Arguments<'a> {
- Arguments{ fmt: cast::transmute(fmt), args: args }
- }
-}
-
-/// This structure represents a safely precompiled version of a format string
-/// and its arguments. This cannot be generated at runtime because it cannot
-/// safely be done so, so no constructors are given and the fields are private
-/// to prevent modification.
-///
-/// The `format_args!` macro will safely create an instance of this structure
-/// and pass it to a user-supplied function. The macro validates the format
-/// string at compile-time so usage of the `write` and `format` functions can
-/// be safely performed.
-pub struct Arguments<'self> {
- priv fmt: &'self [rt::Piece<'self>],
- priv args: &'self [Argument<'self>],
-}
-
-/// When a format is not otherwise specified, types are formatted by ascribing
-/// to this trait. There is not an explicit way of selecting this trait to be
-/// used for formatting, it is only if no other format is specified.
-#[allow(missing_doc)]
-pub trait Default { fn fmt(&Self, &mut Formatter); }
-
-/// Format trait for the `b` character
-#[allow(missing_doc)]
-pub trait Bool { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `c` character
-#[allow(missing_doc)]
-pub trait Char { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `i` and `d` characters
-#[allow(missing_doc)]
-pub trait Signed { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `u` character
-#[allow(missing_doc)]
-pub trait Unsigned { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `o` character
-#[allow(missing_doc)]
-pub trait Octal { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `b` character
-#[allow(missing_doc)]
-pub trait Binary { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `x` character
-#[allow(missing_doc)]
-pub trait LowerHex { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `X` character
-#[allow(missing_doc)]
-pub trait UpperHex { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `s` character
-#[allow(missing_doc)]
-pub trait String { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `?` character
-#[allow(missing_doc)]
-pub trait Poly { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `p` character
-#[allow(missing_doc)]
-pub trait Pointer { fn fmt(&Self, &mut Formatter); }
-/// Format trait for the `f` character
-#[allow(missing_doc)]
-pub trait Float { fn fmt(&Self, &mut Formatter); }
-
-/// The `write` function takes an output stream, a precompiled format string,
-/// and a list of arguments. The arguments will be formatted according to the
-/// specified format string into the output stream provided.
-///
-/// # Arguments
-///
-/// * output - the buffer to write output to
-/// * args - the precompiled arguments generated by `format_args!`
-///
-/// # Example
-///
-/// ```rust
-/// use std::fmt;
-/// let w: &mut io::Writer = ...;
-/// format_args!(|args| { fmt::write(w, args) }, "Hello, {}!", "world");
-/// ```
-pub fn write(output: &mut io::Writer, args: &Arguments) {
- unsafe { write_unsafe(output, args.fmt, args.args) }
-}
-
-/// The `writeln` function takes the same arguments as `write`, except that it
-/// will also write a newline (`\n`) character at the end of the format string.
-pub fn writeln(output: &mut io::Writer, args: &Arguments) {
- unsafe { write_unsafe(output, args.fmt, args.args) }
- output.write(['\n' as u8]);
-}
-
-/// The `write_unsafe` function takes an output stream, a precompiled format
-/// string, and a list of arguments. The arguments will be formatted according
-/// to the specified format string into the output stream provided.
-///
-/// See the documentation for `format` for why this function is unsafe and care
-/// should be taken if calling it manually.
-///
-/// Thankfully the rust compiler provides the macro `fmtf!` which will perform
-/// all of this validation at compile-time and provides a safe interface for
-/// invoking this function.
-///
-/// # Arguments
-///
-/// * output - the buffer to write output to
-/// * fmts - the precompiled format string to emit
-/// * args - the list of arguments to the format string. These are only the
-/// positional arguments (not named)
-///
-/// Note that this function assumes that there are enough arguments for the
-/// format string.
-pub unsafe fn write_unsafe(output: &mut io::Writer,
- fmt: &[rt::Piece],
- args: &[Argument]) {
- let mut formatter = Formatter {
- flags: 0,
- width: None,
- precision: None,
- buf: output,
- align: parse::AlignUnknown,
- fill: ' ',
- args: args,
- curarg: args.iter(),
- };
- for piece in fmt.iter() {
- formatter.run(piece, None);
- }
-}
-
-/// The format function takes a precompiled format string and a list of
-/// arguments, to return the resulting formatted string.
-///
-/// # Arguments
-///
-/// * args - a structure of arguments generated via the `format_args!` macro.
-/// Because this structure can only be safely generated at
-/// compile-time, this function is safe.
-///
-/// # Example
-///
-/// ```rust
-/// use std::fmt;
-/// let s = format_args!(fmt::format, "Hello, {}!", "world");
-/// assert_eq!(s, "Hello, world!");
-/// ```
-pub fn format(args: &Arguments) -> ~str {
- unsafe { format_unsafe(args.fmt, args.args) }
-}
-
-/// The unsafe version of the formatting function.
-///
-/// This is currently an unsafe function because the types of all arguments
-/// aren't verified by immediate callers of this function. This currently does
-/// not validate that the correct types of arguments are specified for each
-/// format specifier, nor that each argument itself contains the right function
-/// for formatting the right type value. Because of this, the function is marked
-/// as `unsafe` if this is being called manually.
-///
-/// Thankfully the rust compiler provides the macro `format!` which will perform
-/// all of this validation at compile-time and provides a safe interface for
-/// invoking this function.
-///
-/// # Arguments
-///
-/// * fmts - the precompiled format string to emit.
-/// * args - the list of arguments to the format string. These are only the
-/// positional arguments (not named)
-///
-/// Note that this function assumes that there are enough arguments for the
-/// format string.
-pub unsafe fn format_unsafe(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
- let mut output = MemWriter::new();
- write_unsafe(&mut output as &mut io::Writer, fmt, args);
- return str::from_utf8_owned(output.inner());
-}
-
-impl<'self> Formatter<'self> {
-
- // First up is the collection of functions used to execute a format string
- // at runtime. This consumes all of the compile-time statics generated by
- // the format! syntax extension.
-
- fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
- match *piece {
- rt::String(s) => { self.buf.write(s.as_bytes()); }
- rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()); }
- rt::Argument(ref arg) => {
- // Fill in the format parameters into the formatter
- self.fill = arg.format.fill;
- self.align = arg.format.align;
- self.flags = arg.format.flags;
- self.width = self.getcount(&arg.format.width);
- self.precision = self.getcount(&arg.format.precision);
-
- // Extract the correct argument
- let value = match arg.position {
- rt::ArgumentNext => { *self.curarg.next().unwrap() }
- rt::ArgumentIs(i) => self.args[i],
- };
-
- // Then actually do some printing
- match arg.method {
- None => { (value.formatter)(value.value, self); }
- Some(ref method) => { self.execute(*method, value); }
- }
- }
- }
- }
-
- fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
- match *cnt {
- rt::CountIs(n) => { Some(n) }
- rt::CountImplied => { None }
- rt::CountIsParam(i) => {
- let v = self.args[i].value;
- unsafe { Some(*(v as *util::Void as *uint)) }
- }
- rt::CountIsNextParam => {
- let v = self.curarg.next().unwrap().value;
- unsafe { Some(*(v as *util::Void as *uint)) }
- }
- }
- }
-
- fn execute(&mut self, method: &rt::Method, arg: Argument) {
- match *method {
- // Pluralization is selection upon a numeric value specified as the
- // parameter.
- rt::Plural(offset, ref selectors, ref default) => {
- // This is validated at compile-time to be a pointer to a
- // '&uint' value.
- let value: &uint = unsafe { cast::transmute(arg.value) };
- let value = *value;
-
- // First, attempt to match against explicit values without the
- // offsetted value
- for s in selectors.iter() {
- match s.selector {
- Right(val) if value == val => {
- return self.runplural(value, s.result);
- }
- _ => {}
- }
- }
-
- // Next, offset the value and attempt to match against the
- // keyword selectors.
- let value = value - match offset { Some(i) => i, None => 0 };
- for s in selectors.iter() {
- let run = match s.selector {
- Left(parse::Zero) => value == 0,
- Left(parse::One) => value == 1,
- Left(parse::Two) => value == 2,
-
- // XXX: Few/Many should have a user-specified boundary
- // One possible option would be in the function
- // pointer of the 'arg: Argument' struct.
- Left(parse::Few) => value < 8,
- Left(parse::Many) => value >= 8,
-
- Right(..) => false
- };
- if run {
- return self.runplural(value, s.result);
- }
- }
-
- self.runplural(value, *default);
- }
-
- // Select is just a matching against the string specified.
- rt::Select(ref selectors, ref default) => {
- // This is validated at compile-time to be a pointer to a
- // string slice,
- let value: & &str = unsafe { cast::transmute(arg.value) };
- let value = *value;
-
- for s in selectors.iter() {
- if s.selector == value {
- for piece in s.result.iter() {
- self.run(piece, Some(value));
- }
- return;
- }
- }
- for piece in default.iter() {
- self.run(piece, Some(value));
- }
- }
- }
- }
-
- fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) {
- ::uint::to_str_bytes(value, 10, |buf| {
- let valuestr = str::from_utf8_slice(buf);
- for piece in pieces.iter() {
- self.run(piece, Some(valuestr));
- }
- })
- }
-
- // Helper methods used for padding and processing formatting arguments that
- // all formatting traits can use.
-
- /// Performs the correct padding for an integer which has already been
- /// emitted into a byte-array. The byte-array should *not* contain the sign
- /// for the integer, that will be added by this method.
- ///
- /// # Arguments
- ///
- /// * s - the byte array that the number has been formatted into
- /// * alternate_prefix - if the '#' character (FlagAlternate) is
- /// provided, this is the prefix to put in front of the number.
- /// Currently this is 0x/0o/0b/etc.
- /// * positive - whether the original integer was positive or not.
- ///
- /// This function will correctly account for the flags provided as well as
- /// the minimum width. It will not take precision into account.
- pub fn pad_integral(&mut self, s: &[u8], alternate_prefix: &str,
- positive: bool) {
- use fmt::parse::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
-
- let mut actual_len = s.len();
- if self.flags & 1 << (FlagAlternate as uint) != 0 {
- actual_len += alternate_prefix.len();
- }
- if self.flags & 1 << (FlagSignPlus as uint) != 0 {
- actual_len += 1;
- } else if !positive {
- actual_len += 1;
- }
-
- let mut signprinted = false;
- let sign = |this: &mut Formatter| {
- if !signprinted {
- if this.flags & 1 << (FlagSignPlus as uint) != 0 && positive {
- this.buf.write(['+' as u8]);
- } else if !positive {
- this.buf.write(['-' as u8]);
- }
- if this.flags & 1 << (FlagAlternate as uint) != 0 {
- this.buf.write(alternate_prefix.as_bytes());
- }
- signprinted = true;
- }
- };
-
- let emit = |this: &mut Formatter| {
- sign(this);
- this.buf.write(s);
- };
-
- match self.width {
- None => { emit(self) }
- Some(min) if actual_len >= min => { emit(self) }
- Some(min) => {
- if self.flags & 1 << (FlagSignAwareZeroPad as uint) != 0 {
- self.fill = '0';
- sign(self);
- }
- self.with_padding(min - actual_len, parse::AlignRight, |me| {
- emit(me);
- })
- }
- }
- }
-
- /// This function takes a string slice and emits it to the internal buffer
- /// after applying the relevant formatting flags specified. The flags
- /// recognized for generic strings are:
- ///
- /// * width - the minimum width of what to emit
- /// * fill/align - what to emit and where to emit it if the string
- /// provided needs to be padded
- /// * precision - the maximum length to emit, the string is truncated if it
- /// is longer than this length
- ///
- /// Notably this function ignored the `flag` parameters
- pub fn pad(&mut self, s: &str) {
- // Make sure there's a fast path up front
- if self.width.is_none() && self.precision.is_none() {
- self.buf.write(s.as_bytes());
- return
- }
- // The `precision` field can be interpreted as a `max-width` for the
- // string being formatted
- match self.precision {
- Some(max) => {
- // If there's a maximum width and our string is longer than
- // that, then we must always have truncation. This is the only
- // case where the maximum length will matter.
- let char_len = s.char_len();
- if char_len >= max {
- let nchars = ::uint::min(max, char_len);
- self.buf.write(s.slice_chars(0, nchars).as_bytes());
- return
- }
- }
- None => {}
- }
-
- // The `width` field is more of a `min-width` parameter at this point.
- match self.width {
- // If we're under the maximum length, and there's no minimum length
- // requirements, then we can just emit the string
- None => { self.buf.write(s.as_bytes()) }
-
- // If we're under the maximum width, check if we're over the minimum
- // width, if so it's as easy as just emitting the string.
- Some(width) if s.char_len() >= width => {
- self.buf.write(s.as_bytes())
- }
-
- // If we're under both the maximum and the minimum width, then fill
- // up the minimum width with the specified string + some alignment.
- Some(width) => {
- self.with_padding(width - s.len(), parse::AlignLeft, |me| {
- me.buf.write(s.as_bytes());
- })
- }
- }
- }
-
- fn with_padding(&mut self,
- padding: uint,
- default: parse::Alignment,
- f: |&mut Formatter|) {
- let align = match self.align {
- parse::AlignUnknown => default,
- parse::AlignLeft | parse::AlignRight => self.align
- };
- if align == parse::AlignLeft {
- f(self);
- }
- let mut fill = [0u8, ..4];
- let len = self.fill.encode_utf8(fill);
- for _ in range(0, padding) {
- self.buf.write(fill.slice_to(len));
- }
- if align == parse::AlignRight {
- f(self);
- }
- }
-}
-
-/// This is a function which calls are emitted to by the compiler itself to
-/// create the Argument structures that are passed into the `format` function.
-#[doc(hidden)] #[inline]
-pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter),
- t: &'a T) -> Argument<'a> {
- unsafe {
- Argument {
- formatter: cast::transmute(f),
- value: cast::transmute(t)
- }
- }
-}
-
-/// When the compiler determines that the type of an argument *must* be a string
-/// (such as for select), then it invokes this method.
-#[doc(hidden)] #[inline]
-pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
- argument(String::fmt, s)
-}
-
-/// When the compiler determines that the type of an argument *must* be a uint
-/// (such as for plural), then it invokes this method.
-#[doc(hidden)] #[inline]
-pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
- argument(Unsigned::fmt, s)
-}
-
-// Implementations of the core formatting traits
-
-impl Bool for bool {
- fn fmt(b: &bool, f: &mut Formatter) {
- String::fmt(&(if *b {"true"} else {"false"}), f);
- }
-}
-
-impl<'self, T: str::Str> String for T {
- fn fmt(s: &T, f: &mut Formatter) {
- f.pad(s.as_slice());
- }
-}
-
-impl Char for char {
- fn fmt(c: &char, f: &mut Formatter) {
- let mut utf8 = [0u8, ..4];
- let amt = c.encode_utf8(utf8);
- let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) };
- String::fmt(&s, f);
- }
-}
-
-macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
- $name:ident, $prefix:expr) => {
- impl $name for $ty {
- fn fmt(c: &$ty, f: &mut Formatter) {
- ::$into::to_str_bytes(*c as $into, $base, |buf| {
- f.pad_integral(buf, $prefix, true);
- })
- }
- }
-})
-macro_rules! upper_hex(($ty:ident, $into:ident) => {
- impl UpperHex for $ty {
- fn fmt(c: &$ty, f: &mut Formatter) {
- ::$into::to_str_bytes(*c as $into, 16, |buf| {
- upperhex(buf, f);
- })
- }
- }
-})
-// Not sure why, but this causes an "unresolved enum variant, struct or const"
-// when inlined into the above macro...
-#[doc(hidden)]
-pub fn upperhex(buf: &[u8], f: &mut Formatter) {
- let mut local = [0u8, ..16];
- for i in ::iter::range(0, buf.len()) {
- local[i] = match buf[i] as char {
- 'a' .. 'f' => (buf[i] - 'a' as u8) + 'A' as u8,
- c => c as u8,
- }
- }
- f.pad_integral(local.slice_to(buf.len()), "0x", true);
-}
-
-// FIXME(#4375) shouldn't need an inner module
-macro_rules! integer(($signed:ident, $unsigned:ident) => {
- mod $signed {
- use super::*;
-
- // Signed is special because it actuall emits the negative sign,
- // nothing else should do that, however.
- impl Signed for $signed {
- fn fmt(c: &$signed, f: &mut Formatter) {
- ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
- f.pad_integral(buf, "", *c >= 0);
- })
- }
- }
- int_base!($signed, $unsigned, 2, Binary, "0b")
- int_base!($signed, $unsigned, 8, Octal, "0o")
- int_base!($signed, $unsigned, 16, LowerHex, "0x")
- upper_hex!($signed, $unsigned)
-
- int_base!($unsigned, $unsigned, 2, Binary, "0b")
- int_base!($unsigned, $unsigned, 8, Octal, "0o")
- int_base!($unsigned, $unsigned, 10, Unsigned, "")
- int_base!($unsigned, $unsigned, 16, LowerHex, "0x")
- upper_hex!($unsigned, $unsigned)
- }
-})
-
-integer!(int, uint)
-integer!(i8, u8)
-integer!(i16, u16)
-integer!(i32, u32)
-integer!(i64, u64)
-
-macro_rules! floating(($ty:ident) => {
- impl Float for $ty {
- fn fmt(f: &$ty, fmt: &mut Formatter) {
- // XXX: this shouldn't perform an allocation
- let s = match fmt.precision {
- Some(i) => ::$ty::to_str_exact(f.abs(), i),
- None => ::$ty::to_str_digits(f.abs(), 6)
- };
- fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
- }
- }
-})
-floating!(f32)
-floating!(f64)
-
-impl<T> Poly for T {
- fn fmt(t: &T, f: &mut Formatter) {
- match (f.width, f.precision) {
- (None, None) => {
- repr::write_repr(f.buf, t);
- }
-
- // If we have a specified width for formatting, then we have to make
- // this allocation of a new string
- _ => {
- let s = repr::repr_to_str(t);
- f.pad(s);
- }
- }
- }
-}
-
-impl<T> Pointer for *T {
- fn fmt(t: &*T, f: &mut Formatter) {
- f.flags |= 1 << (parse::FlagAlternate as uint);
- ::uint::to_str_bytes(*t as uint, 16, |buf| {
- f.pad_integral(buf, "0x", true);
- })
- }
-}
-impl<T> Pointer for *mut T {
- fn fmt(t: &*mut T, f: &mut Formatter) { Pointer::fmt(&(*t as *T), f) }
-}
-
-// Implementation of Default for various core types
-
-macro_rules! delegate(($ty:ty to $other:ident) => {
- impl<'self> Default for $ty {
- fn fmt(me: &$ty, f: &mut Formatter) {
- $other::fmt(me, f)
- }
- }
-})
-delegate!(int to Signed)
-delegate!( i8 to Signed)
-delegate!(i16 to Signed)
-delegate!(i32 to Signed)
-delegate!(i64 to Signed)
-delegate!(uint to Unsigned)
-delegate!( u8 to Unsigned)
-delegate!( u16 to Unsigned)
-delegate!( u32 to Unsigned)
-delegate!( u64 to Unsigned)
-delegate!(@str to String)
-delegate!(~str to String)
-delegate!(&'self str to String)
-delegate!(bool to Bool)
-delegate!(char to Char)
-delegate!(f32 to Float)
-delegate!(f64 to Float)
-
-impl<T> Default for *T {
- fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) }
-}
-impl<T> Default for *mut T {
- fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) }
-}
-
-// If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
-// it's a lot easier than creating all of the rt::Piece structures here.
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Parsing of format strings
-//!
-//! These structures are used when parsing format strings for the compiler.
-//! Parsing does not currently happen at runtime (structures of std::fmt::rt are
-//! generated instead).
-
-use prelude::*;
-
-use char;
-use str;
-
-condition! { pub parse_error: ~str -> (); }
-
-/// A piece is a portion of the format string which represents the next part to
-/// emit. These are emitted as a stream by the `Parser` class.
-#[deriving(Eq)]
-pub enum Piece<'self> {
- /// A literal string which should directly be emitted
- String(&'self str),
- /// A back-reference to whatever the current argument is. This is used
- /// inside of a method call to refer back to the original argument.
- CurrentArgument,
- /// This describes that formatting should process the next argument (as
- /// specified inside) for emission.
- Argument(Argument<'self>),
-}
-
-/// Representation of an argument specification.
-#[deriving(Eq)]
-pub struct Argument<'self> {
- /// Where to find this argument
- position: Position<'self>,
- /// How to format the argument
- format: FormatSpec<'self>,
- /// If not `None`, what method to invoke on the argument
- method: Option<~Method<'self>>
-}
-
-/// Specification for the formatting of an argument in the format string.
-#[deriving(Eq)]
-pub struct FormatSpec<'self> {
- /// Optionally specified character to fill alignment with
- fill: Option<char>,
- /// Optionally specified alignment
- align: Alignment,
- /// Packed version of various flags provided
- flags: uint,
- /// The integer precision to use
- precision: Count<'self>,
- /// The string width requested for the resulting format
- width: Count<'self>,
- /// The descriptor string representing the name of the format desired for
- /// this argument, this can be empty or any number of characters, although
- /// it is required to be one word.
- ty: &'self str
-}
-
-/// Enum describing where an argument for a format can be located.
-#[deriving(Eq)]
-#[allow(missing_doc)]
-pub enum Position<'self> {
- ArgumentNext, ArgumentIs(uint), ArgumentNamed(&'self str)
-}
-
-/// Enum of alignments which are supported.
-#[deriving(Eq)]
-#[allow(missing_doc)]
-pub enum Alignment { AlignLeft, AlignRight, AlignUnknown }
-
-/// Various flags which can be applied to format strings, the meaning of these
-/// flags is defined by the formatters themselves.
-#[deriving(Eq)]
-#[allow(missing_doc)]
-pub enum Flag {
- FlagSignPlus,
- FlagSignMinus,
- FlagAlternate,
- FlagSignAwareZeroPad,
-}
-
-/// A count is used for the precision and width parameters of an integer, and
-/// can reference either an argument or a literal integer.
-#[deriving(Eq)]
-#[allow(missing_doc)]
-pub enum Count<'self> {
- CountIs(uint),
- CountIsName(&'self str),
- CountIsParam(uint),
- CountIsNextParam,
- CountImplied,
-}
-
-/// Enum describing all of the possible methods which the formatting language
-/// currently supports.
-#[deriving(Eq)]
-pub enum Method<'self> {
- /// A plural method selects on an integer over a list of either integer or
- /// keyword-defined clauses. The meaning of the keywords is defined by the
- /// current locale.
- ///
- /// An offset is optionally present at the beginning which is used to match
- /// against keywords, but it is not matched against the literal integers.
- ///
- /// The final element of this enum is the default "other" case which is
- /// always required to be specified.
- Plural(Option<uint>, ~[PluralArm<'self>], ~[Piece<'self>]),
-
- /// A select method selects over a string. Each arm is a different string
- /// which can be selected for.
- ///
- /// As with `Plural`, a default "other" case is required as well.
- Select(~[SelectArm<'self>], ~[Piece<'self>]),
-}
-
-/// Structure representing one "arm" of the `plural` function.
-#[deriving(Eq)]
-pub struct PluralArm<'self> {
- /// A selector can either be specified by a keyword or with an integer
- /// literal.
- selector: Either<PluralKeyword, uint>,
- /// Array of pieces which are the format of this arm
- result: ~[Piece<'self>],
-}
-
-/// Enum of the 5 CLDR plural keywords. There is one more, "other", but that is
-/// specially placed in the `Plural` variant of `Method`
-///
-/// http://www.icu-project.org/apiref/icu4c/classicu_1_1PluralRules.html
-#[deriving(Eq, IterBytes)]
-#[allow(missing_doc)]
-pub enum PluralKeyword {
- Zero, One, Two, Few, Many
-}
-
-/// Structure representing one "arm" of the `select` function.
-#[deriving(Eq)]
-pub struct SelectArm<'self> {
- /// String selector which guards this arm
- selector: &'self str,
- /// Array of pieces which are the format of this arm
- result: ~[Piece<'self>],
-}
-
-/// The parser structure for interpreting the input format string. This is
-/// modelled as an iterator over `Piece` structures to form a stream of tokens
-/// being output.
-///
-/// This is a recursive-descent parser for the sake of simplicity, and if
-/// necessary there's probably lots of room for improvement performance-wise.
-pub struct Parser<'self> {
- priv input: &'self str,
- priv cur: str::CharOffsetIterator<'self>,
- priv depth: uint,
-}
-
-impl<'self> Iterator<Piece<'self>> for Parser<'self> {
- fn next(&mut self) -> Option<Piece<'self>> {
- match self.cur.clone().next() {
- Some((_, '#')) => { self.cur.next(); Some(CurrentArgument) }
- Some((_, '{')) => {
- self.cur.next();
- let ret = Some(Argument(self.argument()));
- self.must_consume('}');
- ret
- }
- Some((pos, '\\')) => {
- self.cur.next();
- self.escape(); // ensure it's a valid escape sequence
- Some(String(self.string(pos + 1))) // skip the '\' character
- }
- Some((_, '}')) if self.depth == 0 => {
- self.cur.next();
- self.err("unmatched `}` found");
- None
- }
- Some((_, '}')) | None => { None }
- Some((pos, _)) => {
- Some(String(self.string(pos)))
- }
- }
- }
-}
-
-impl<'self> Parser<'self> {
- /// Creates a new parser for the given format string
- pub fn new<'a>(s: &'a str) -> Parser<'a> {
- Parser {
- input: s,
- cur: s.char_indices(),
- depth: 0,
- }
- }
-
- /// Notifies of an error. The message doesn't actually need to be of type
- /// ~str, but I think it does when this eventually uses conditions so it
- /// might as well start using it now.
- fn err(&self, msg: &str) {
- parse_error::cond.raise("invalid format string: " + msg);
- }
-
- /// Optionally consumes the specified character. If the character is not at
- /// the current position, then the current iterator isn't moved and false is
- /// returned, otherwise the character is consumed and true is returned.
- fn consume(&mut self, c: char) -> bool {
- match self.cur.clone().next() {
- Some((_, maybe)) if c == maybe => {
- self.cur.next();
- true
- }
- Some(..) | None => false,
- }
- }
-
- /// Forces consumption of the specified character. If the character is not
- /// found, an error is emitted.
- fn must_consume(&mut self, c: char) {
- self.ws();
- match self.cur.clone().next() {
- Some((_, maybe)) if c == maybe => {
- self.cur.next();
- }
- Some((_, other)) => {
- self.err(
- format!("expected `{}` but found `{}`", c, other));
- }
- None => {
- self.err(
- format!("expected `{}` but string was terminated", c));
- }
- }
- }
-
- /// Attempts to consume any amount of whitespace followed by a character
- fn wsconsume(&mut self, c: char) -> bool {
- self.ws(); self.consume(c)
- }
-
- /// Consumes all whitespace characters until the first non-whitespace
- /// character
- fn ws(&mut self) {
- loop {
- match self.cur.clone().next() {
- Some((_, c)) if char::is_whitespace(c) => { self.cur.next(); }
- Some(..) | None => { return }
- }
- }
- }
-
- /// Consumes an escape sequence, failing if there is not a valid character
- /// to be escaped.
- fn escape(&mut self) -> char {
- match self.cur.next() {
- Some((_, c @ '#')) | Some((_, c @ '{')) |
- Some((_, c @ '\\')) | Some((_, c @ '}')) => { c }
- Some((_, c)) => {
- self.err(format!("invalid escape character `{}`", c));
- c
- }
- None => {
- self.err("expected an escape sequence, but format string was \
- terminated");
- ' '
- }
- }
- }
-
- /// Parses all of a string which is to be considered a "raw literal" in a
- /// format string. This is everything outside of the braces.
- fn string(&mut self, start: uint) -> &'self str {
- loop {
- // we may not consume the character, so clone the iterator
- match self.cur.clone().next() {
- Some((pos, '\\')) | Some((pos, '#')) |
- Some((pos, '}')) | Some((pos, '{')) => {
- return self.input.slice(start, pos);
- }
- Some(..) => { self.cur.next(); }
- None => {
- self.cur.next();
- return self.input.slice(start, self.input.len());
- }
- }
- }
- }
-
- /// Parses an Argument structure, or what's contained within braces inside
- /// the format string
- fn argument(&mut self) -> Argument<'self> {
- Argument {
- position: self.position(),
- format: self.format(),
- method: self.method(),
- }
- }
-
- /// Parses a positional argument for a format. This could either be an
- /// integer index of an argument, a named argument, or a blank string.
- fn position(&mut self) -> Position<'self> {
- match self.integer() {
- Some(i) => { ArgumentIs(i) }
- None => {
- match self.cur.clone().next() {
- Some((_, c)) if char::is_alphabetic(c) => {
- ArgumentNamed(self.word())
- }
- _ => ArgumentNext
- }
- }
- }
- }
-
- /// Parses a format specifier at the current position, returning all of the
- /// relevant information in the FormatSpec struct.
- fn format(&mut self) -> FormatSpec<'self> {
- let mut spec = FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: self.input.slice(0, 0),
- };
- if !self.consume(':') { return spec }
-
- // fill character
- match self.cur.clone().next() {
- Some((_, c)) => {
- match self.cur.clone().skip(1).next() {
- Some((_, '>')) | Some((_, '<')) => {
- spec.fill = Some(c);
- self.cur.next();
- }
- Some(..) | None => {}
- }
- }
- None => {}
- }
- // Alignment
- if self.consume('<') {
- spec.align = AlignLeft;
- } else if self.consume('>') {
- spec.align = AlignRight;
- }
- // Sign flags
- if self.consume('+') {
- spec.flags |= 1 << (FlagSignPlus as uint);
- } else if self.consume('-') {
- spec.flags |= 1 << (FlagSignMinus as uint);
- }
- // Alternate marker
- if self.consume('#') {
- spec.flags |= 1 << (FlagAlternate as uint);
- }
- // Width and precision
- let mut havewidth = false;
- if self.consume('0') {
- // small ambiguity with '0$' as a format string. In theory this is a
- // '0' flag and then an ill-formatted format string with just a '$'
- // and no count, but this is better if we instead interpret this as
- // no '0' flag and '0$' as the width instead.
- if self.consume('$') {
- spec.width = CountIsParam(0);
- havewidth = true;
- } else {
- spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
- }
- }
- if !havewidth {
- spec.width = self.count();
- }
- if self.consume('.') {
- if self.consume('*') {
- spec.precision = CountIsNextParam;
- } else {
- spec.precision = self.count();
- }
- }
- // Finally the actual format specifier
- if self.consume('?') {
- spec.ty = "?";
- } else {
- spec.ty = self.word();
- }
- return spec;
- }
-
- /// Parses a method to be applied to the previously specified argument and
- /// its format. The two current supported methods are 'plural' and 'select'
- fn method(&mut self) -> Option<~Method<'self>> {
- if !self.wsconsume(',') {
- return None;
- }
- self.ws();
- match self.word() {
- "select" => {
- self.must_consume(',');
- Some(self.select())
- }
- "plural" => {
- self.must_consume(',');
- Some(self.plural())
- }
- "" => {
- self.err("expected method after comma");
- return None;
- }
- method => {
- self.err(format!("unknown method: `{}`", method));
- return None;
- }
- }
- }
-
- /// Parses a 'select' statement (after the initial 'select' word)
- fn select(&mut self) -> ~Method<'self> {
- let mut other = None;
- let mut arms = ~[];
- // Consume arms one at a time
- loop {
- self.ws();
- let selector = self.word();
- if selector == "" {
- self.err("cannot have an empty selector");
- break
- }
- self.must_consume('{');
- self.depth += 1;
- let pieces = self.collect();
- self.depth -= 1;
- self.must_consume('}');
- if selector == "other" {
- if !other.is_none() {
- self.err("multiple `other` statements in `select");
- }
- other = Some(pieces);
- } else {
- arms.push(SelectArm { selector: selector, result: pieces });
- }
- self.ws();
- match self.cur.clone().next() {
- Some((_, '}')) => { break }
- Some(..) | None => {}
- }
- }
- // The "other" selector must be present
- let other = match other {
- Some(arm) => { arm }
- None => {
- self.err("`select` statement must provide an `other` case");
- ~[]
- }
- };
- ~Select(arms, other)
- }
-
- /// Parses a 'plural' statement (after the initial 'plural' word)
- fn plural(&mut self) -> ~Method<'self> {
- let mut offset = None;
- let mut other = None;
- let mut arms = ~[];
-
- // First, attempt to parse the 'offset:' field. We know the set of
- // selector words which can appear in plural arms, and the only ones
- // which start with 'o' are "other" and "offset", hence look two
- // characters deep to see if we can consume the word "offset"
- self.ws();
- let mut it = self.cur.clone();
- match it.next() {
- Some((_, 'o')) => {
- match it.next() {
- Some((_, 'f')) => {
- let word = self.word();
- if word != "offset" {
- self.err(format!("expected `offset`, found `{}`",
- word));
- } else {
- self.must_consume(':');
- match self.integer() {
- Some(i) => { offset = Some(i); }
- None => {
- self.err("offset must be an integer");
- }
- }
- }
- }
- Some(..) | None => {}
- }
- }
- Some(..) | None => {}
- }
-
- // Next, generate all the arms
- loop {
- let mut isother = false;
- let selector = if self.wsconsume('=') {
- match self.integer() {
- Some(i) => Right(i),
- None => {
- self.err("plural `=` selectors must be followed by an \
- integer");
- Right(0)
- }
- }
- } else {
- let word = self.word();
- match word {
- "other" => { isother = true; Left(Zero) }
- "zero" => Left(Zero),
- "one" => Left(One),
- "two" => Left(Two),
- "few" => Left(Few),
- "many" => Left(Many),
- word => {
- self.err(format!("unexpected plural selector `{}`",
- word));
- if word == "" {
- break
- } else {
- Left(Zero)
- }
- }
- }
- };
- self.must_consume('{');
- self.depth += 1;
- let pieces = self.collect();
- self.depth -= 1;
- self.must_consume('}');
- if isother {
- if !other.is_none() {
- self.err("multiple `other` statements in `select");
- }
- other = Some(pieces);
- } else {
- arms.push(PluralArm { selector: selector, result: pieces });
- }
- self.ws();
- match self.cur.clone().next() {
- Some((_, '}')) => { break }
- Some(..) | None => {}
- }
- }
-
- let other = match other {
- Some(arm) => { arm }
- None => {
- self.err("`plural` statement must provide an `other` case");
- ~[]
- }
- };
- ~Plural(offset, arms, other)
- }
-
- /// Parses a Count parameter at the current position. This does not check
- /// for 'CountIsNextParam' because that is only used in precision, not
- /// width.
- fn count(&mut self) -> Count<'self> {
- match self.integer() {
- Some(i) => {
- if self.consume('$') {
- CountIsParam(i)
- } else {
- CountIs(i)
- }
- }
- None => {
- let tmp = self.cur.clone();
- match self.word() {
- word if word.len() > 0 && self.consume('$') => {
- CountIsName(word)
- }
- _ => {
- self.cur = tmp;
- CountImplied
- }
- }
- }
- }
- }
-
- /// Parses a word starting at the current position. A word is considered to
- /// be an alphabetic character followed by any number of alphanumeric
- /// characters.
- fn word(&mut self) -> &'self str {
- let start = match self.cur.clone().next() {
- Some((pos, c)) if char::is_XID_start(c) => {
- self.cur.next();
- pos
- }
- Some(..) | None => { return self.input.slice(0, 0); }
- };
- let mut end;
- loop {
- match self.cur.clone().next() {
- Some((_, c)) if char::is_XID_continue(c) => {
- self.cur.next();
- }
- Some((pos, _)) => { end = pos; break }
- None => { end = self.input.len(); break }
- }
- }
- self.input.slice(start, end)
- }
-
- /// Optionally parses an integer at the current position. This doesn't deal
- /// with overflow at all, it's just accumulating digits.
- fn integer(&mut self) -> Option<uint> {
- let mut cur = 0;
- let mut found = false;
- loop {
- match self.cur.clone().next() {
- Some((_, c)) => {
- match char::to_digit(c, 10) {
- Some(i) => {
- cur = cur * 10 + i;
- found = true;
- self.cur.next();
- }
- None => { break }
- }
- }
- None => { break }
- }
- }
- if found {
- return Some(cur);
- } else {
- return None;
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use prelude::*;
-
- fn same(fmt: &'static str, p: ~[Piece<'static>]) {
- let mut parser = Parser::new(fmt);
- assert_eq!(p, parser.collect());
- }
-
- fn fmtdflt() -> FormatSpec<'static> {
- return FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: "",
- }
- }
-
- fn musterr(s: &str) {
- Parser::new(s).next();
- }
-
- #[test]
- fn simple() {
- same("asdf", ~[String("asdf")]);
- same("a\\{b", ~[String("a"), String("{b")]);
- same("a\\#b", ~[String("a"), String("#b")]);
- same("a\\}b", ~[String("a"), String("}b")]);
- same("a\\}", ~[String("a"), String("}")]);
- same("\\}", ~[String("}")]);
- }
-
- #[test] #[should_fail] fn invalid01() { musterr("{") }
- #[test] #[should_fail] fn invalid02() { musterr("\\") }
- #[test] #[should_fail] fn invalid03() { musterr("\\a") }
- #[test] #[should_fail] fn invalid04() { musterr("{3a}") }
- #[test] #[should_fail] fn invalid05() { musterr("{:|}") }
- #[test] #[should_fail] fn invalid06() { musterr("{:>>>}") }
-
- #[test]
- fn format_nothing() {
- same("{}", ~[Argument(Argument {
- position: ArgumentNext,
- format: fmtdflt(),
- method: None,
- })]);
- }
- #[test]
- fn format_position() {
- same("{3}", ~[Argument(Argument {
- position: ArgumentIs(3),
- format: fmtdflt(),
- method: None,
- })]);
- }
- #[test]
- fn format_position_nothing_else() {
- same("{3:}", ~[Argument(Argument {
- position: ArgumentIs(3),
- format: fmtdflt(),
- method: None,
- })]);
- }
- #[test]
- fn format_type() {
- same("{3:a}", ~[Argument(Argument {
- position: ArgumentIs(3),
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: "a",
- },
- method: None,
- })]);
- }
- #[test]
- fn format_align_fill() {
- same("{3:>}", ~[Argument(Argument {
- position: ArgumentIs(3),
- format: FormatSpec {
- fill: None,
- align: AlignRight,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: "",
- },
- method: None,
- })]);
- same("{3:0<}", ~[Argument(Argument {
- position: ArgumentIs(3),
- format: FormatSpec {
- fill: Some('0'),
- align: AlignLeft,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: "",
- },
- method: None,
- })]);
- same("{3:*<abcd}", ~[Argument(Argument {
- position: ArgumentIs(3),
- format: FormatSpec {
- fill: Some('*'),
- align: AlignLeft,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: "abcd",
- },
- method: None,
- })]);
- }
- #[test]
- fn format_counts() {
- same("{:10s}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountImplied,
- width: CountIs(10),
- ty: "s",
- },
- method: None,
- })]);
- same("{:10$.10s}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountIs(10),
- width: CountIsParam(10),
- ty: "s",
- },
- method: None,
- })]);
- same("{:.*s}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountIsNextParam,
- width: CountImplied,
- ty: "s",
- },
- method: None,
- })]);
- same("{:.10$s}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountIsParam(10),
- width: CountImplied,
- ty: "s",
- },
- method: None,
- })]);
- same("{:a$.b$s}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountIsName("b"),
- width: CountIsName("a"),
- ty: "s",
- },
- method: None,
- })]);
- }
- #[test]
- fn format_flags() {
- same("{:-}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: (1 << FlagSignMinus as uint),
- precision: CountImplied,
- width: CountImplied,
- ty: "",
- },
- method: None,
- })]);
- same("{:+#}", ~[Argument(Argument {
- position: ArgumentNext,
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: (1 << FlagSignPlus as uint) | (1 << FlagAlternate as uint),
- precision: CountImplied,
- width: CountImplied,
- ty: "",
- },
- method: None,
- })]);
- }
- #[test]
- fn format_mixture() {
- same("abcd {3:a} efg", ~[String("abcd "), Argument(Argument {
- position: ArgumentIs(3),
- format: FormatSpec {
- fill: None,
- align: AlignUnknown,
- flags: 0,
- precision: CountImplied,
- width: CountImplied,
- ty: "a",
- },
- method: None,
- }), String(" efg")]);
- }
-
- #[test]
- fn select_simple() {
- same("{, select, other { haha } }", ~[Argument(Argument{
- position: ArgumentNext,
- format: fmtdflt(),
- method: Some(~Select(~[], ~[String(" haha ")]))
- })]);
- same("{1, select, other { haha } }", ~[Argument(Argument{
- position: ArgumentIs(1),
- format: fmtdflt(),
- method: Some(~Select(~[], ~[String(" haha ")]))
- })]);
- same("{1, select, other {#} }", ~[Argument(Argument{
- position: ArgumentIs(1),
- format: fmtdflt(),
- method: Some(~Select(~[], ~[CurrentArgument]))
- })]);
- same("{1, select, other {{2, select, other {lol}}} }", ~[Argument(Argument{
- position: ArgumentIs(1),
- format: fmtdflt(),
- method: Some(~Select(~[], ~[Argument(Argument{
- position: ArgumentIs(2),
- format: fmtdflt(),
- method: Some(~Select(~[], ~[String("lol")]))
- })])) // wat
- })]);
- }
-
- #[test]
- fn select_cases() {
- same("{1, select, a{1} b{2} c{3} other{4} }", ~[Argument(Argument{
- position: ArgumentIs(1),
- format: fmtdflt(),
- method: Some(~Select(~[
- SelectArm{ selector: "a", result: ~[String("1")] },
- SelectArm{ selector: "b", result: ~[String("2")] },
- SelectArm{ selector: "c", result: ~[String("3")] },
- ], ~[String("4")]))
- })]);
- }
-
- #[test] #[should_fail] fn badselect01() {
- musterr("{select, }")
- }
- #[test] #[should_fail] fn badselect02() {
- musterr("{1, select}")
- }
- #[test] #[should_fail] fn badselect03() {
- musterr("{1, select, }")
- }
- #[test] #[should_fail] fn badselect04() {
- musterr("{1, select, a {}}")
- }
- #[test] #[should_fail] fn badselect05() {
- musterr("{1, select, other }}")
- }
- #[test] #[should_fail] fn badselect06() {
- musterr("{1, select, other {}")
- }
- #[test] #[should_fail] fn badselect07() {
- musterr("{select, other {}")
- }
- #[test] #[should_fail] fn badselect08() {
- musterr("{1 select, other {}")
- }
- #[test] #[should_fail] fn badselect09() {
- musterr("{:d select, other {}")
- }
- #[test] #[should_fail] fn badselect10() {
- musterr("{1:d select, other {}")
- }
-
- #[test]
- fn plural_simple() {
- same("{, plural, other { haha } }", ~[Argument(Argument{
- position: ArgumentNext,
- format: fmtdflt(),
- method: Some(~Plural(None, ~[], ~[String(" haha ")]))
- })]);
- same("{:, plural, other { haha } }", ~[Argument(Argument{
- position: ArgumentNext,
- format: fmtdflt(),
- method: Some(~Plural(None, ~[], ~[String(" haha ")]))
- })]);
- same("{, plural, offset:1 =2{2} =3{3} many{yes} other{haha} }",
- ~[Argument(Argument{
- position: ArgumentNext,
- format: fmtdflt(),
- method: Some(~Plural(Some(1), ~[
- PluralArm{ selector: Right(2), result: ~[String("2")] },
- PluralArm{ selector: Right(3), result: ~[String("3")] },
- PluralArm{ selector: Left(Many), result: ~[String("yes")] }
- ], ~[String("haha")]))
- })]);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This is an internal module used by the ifmt! runtime. These structures are
-//! emitted to static arrays to precompile format strings ahead of time.
-//!
-//! These definitions are similar to their `ct` equivalents, but differ in that
-//! these can be statically allocated and are slightly optimized for the runtime
-
-#[allow(missing_doc)];
-#[doc(hidden)];
-
-use either::Either;
-use fmt::parse;
-use option::Option;
-
-pub enum Piece<'self> {
- String(&'self str),
- // FIXME(#8259): this shouldn't require the unit-value here
- CurrentArgument(()),
- Argument(Argument<'self>),
-}
-
-pub struct Argument<'self> {
- position: Position,
- format: FormatSpec,
- method: Option<&'self Method<'self>>
-}
-
-pub struct FormatSpec {
- fill: char,
- align: parse::Alignment,
- flags: uint,
- precision: Count,
- width: Count,
-}
-
-pub enum Count {
- CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
-}
-
-pub enum Position {
- ArgumentNext, ArgumentIs(uint)
-}
-
-pub enum Method<'self> {
- Plural(Option<uint>, &'self [PluralArm<'self>], &'self [Piece<'self>]),
- Select(&'self [SelectArm<'self>], &'self [Piece<'self>]),
-}
-
-pub struct PluralArm<'self> {
- selector: Either<parse::PluralKeyword, uint>,
- result: &'self [Piece<'self>],
-}
-
-pub struct SelectArm<'self> {
- selector: &'self str,
- result: &'self [Piece<'self>],
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The trait for types that can be created from strings
-
-use option::Option;
-
-/// A trait to abstract the idea of creating a new instance of a type from a
-/// string.
-pub trait FromStr {
- /// Parses a string `s` to return an optional value of this type. If the
- /// string is ill-formatted, the None is returned.
- fn from_str(s: &str) -> Option<Self>;
-}
-
-/// A utility function that just calls FromStr::from_str
-pub fn from_str<A: FromStr>(s: &str) -> Option<A> {
- FromStr::from_str(s)
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! Task-local garbage-collected boxes
-
-The `Gc` type provides shared ownership of an immutable value. Destruction is not deterministic, and
-will occur some time between every `Gc` handle being gone and the end of the task. The garbage
-collector is task-local so `Gc<T>` is not sendable.
-
-*/
-
-use kinds::Send;
-use clone::{Clone, DeepClone};
-
-/// Immutable garbage-collected pointer type
-#[no_send]
-#[deriving(Clone)]
-pub struct Gc<T> {
- priv ptr: @T
-}
-
-impl<T: 'static> Gc<T> {
- /// Construct a new garbage-collected box
- #[inline]
- pub fn new(value: T) -> Gc<T> {
- Gc { ptr: @value }
- }
-}
-
-impl<T: 'static> Gc<T> {
- /// Borrow the value contained in the garbage-collected box
- #[inline]
- pub fn borrow<'r>(&'r self) -> &'r T {
- &*self.ptr
- }
-}
-
-/// The `Send` bound restricts this to acyclic graphs where it is well-defined.
-///
-/// A `Freeze` bound would also work, but `Send` *or* `Freeze` cannot be expressed.
-impl<T: DeepClone + Send + 'static> DeepClone for Gc<T> {
- #[inline]
- fn deep_clone(&self) -> Gc<T> {
- Gc::new(self.borrow().deep_clone())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use cell::RefCell;
-
- #[test]
- fn test_clone() {
- let x = Gc::new(RefCell::new(5));
- let y = x.clone();
- x.borrow().with_mut(|inner| {
- *inner = 20;
- });
- assert_eq!(y.borrow().with(|x| *x), 20);
- }
-
- #[test]
- fn test_deep_clone() {
- let x = Gc::new(RefCell::new(5));
- let y = x.deep_clone();
- x.borrow().with_mut(|inner| {
- *inner = 20;
- });
- assert_eq!(y.borrow().with(|x| *x), 5);
- }
-
- #[test]
- fn test_simple() {
- let x = Gc::new(5);
- assert_eq!(*x.borrow(), 5);
- }
-
- #[test]
- fn test_simple_clone() {
- let x = Gc::new(5);
- let y = x.clone();
- assert_eq!(*x.borrow(), 5);
- assert_eq!(*y.borrow(), 5);
- }
-
- #[test]
- fn test_destructor() {
- let x = Gc::new(~5);
- assert_eq!(**x.borrow(), 5);
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
- * Implementation of SipHash 2-4
- *
- * See: http://131002.net/siphash/
- *
- * Consider this as a main "general-purpose" hash for all hashtables: it
- * runs at good speed (competitive with spooky and city) and permits
- * strong _keyed_ hashing. Key your hashtables from a strong RNG,
- * such as rand::rng.
- *
- * Although the SipHash algorithm is considered to be cryptographically
- * strong, this implementation has not been reviewed for such purposes.
- * As such, all cryptographic uses of this implementation are strongly
- * discouraged.
- */
-
-#[allow(missing_doc)];
-
-use container::Container;
-use iter::Iterator;
-use option::{Some, None};
-use io::Writer;
-use str::OwnedStr;
-use to_bytes::IterBytes;
-use vec::ImmutableVector;
-use num::ToStrRadix;
-
-// Alias `SipState` to `State`.
-pub use State = hash::SipState;
-
-/**
- * Types that can meaningfully be hashed should implement this.
- *
- * Note that this trait is likely to change somewhat as it is
- * closely related to `to_bytes::IterBytes` and in almost all
- * cases presently the two are (and must be) used together.
- *
- * In general, most types only need to implement `IterBytes`,
- * and the implementation of `Hash` below will take care of
- * the rest. This is the recommended approach, since constructing
- * good keyed hash functions is quite difficult.
- */
-pub trait Hash {
- /**
- * Compute a "keyed" hash of the value implementing the trait,
- * taking `k0` and `k1` as "keying" parameters that randomize or
- * otherwise perturb the hash function in such a way that a
- * hash table built using such "keyed hash functions" cannot
- * be made to perform linearly by an attacker controlling the
- * hashtable's contents.
- *
- * In practical terms, we implement this using the SipHash 2-4
- * function and require most types to only implement the
- * IterBytes trait, that feeds SipHash.
- */
- fn hash_keyed(&self, k0: u64, k1: u64) -> u64;
-
- #[inline]
- fn hash(&self) -> u64 { self.hash_keyed(0,0) }
-}
-
-/// Streaming hash-functions should implement this.
-pub trait Streaming {
- fn input(&mut self, &[u8]);
- // These can be refactored some when we have default methods.
- fn result_bytes(&mut self) -> ~[u8];
- fn result_str(&mut self) -> ~str;
- fn result_u64(&mut self) -> u64;
- fn reset(&mut self);
-}
-
-impl<A:IterBytes> Hash for A {
- #[inline]
- fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
- let mut s = State::new(k0, k1);
- self.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- s.result_u64()
- }
-}
-
-fn hash_keyed_2<A: IterBytes,
- B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
- let mut s = State::new(k0, k1);
- a.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- b.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- s.result_u64()
-}
-
-fn hash_keyed_3<A: IterBytes,
- B: IterBytes,
- C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
- let mut s = State::new(k0, k1);
- a.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- b.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- c.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- s.result_u64()
-}
-
-fn hash_keyed_4<A: IterBytes,
- B: IterBytes,
- C: IterBytes,
- D: IterBytes>(
- a: &A,
- b: &B,
- c: &C,
- d: &D,
- k0: u64,
- k1: u64)
- -> u64 {
- let mut s = State::new(k0, k1);
- a.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- b.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- c.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- d.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- s.result_u64()
-}
-
-fn hash_keyed_5<A: IterBytes,
- B: IterBytes,
- C: IterBytes,
- D: IterBytes,
- E: IterBytes>(
- a: &A,
- b: &B,
- c: &C,
- d: &D,
- e: &E,
- k0: u64,
- k1: u64)
- -> u64 {
- let mut s = State::new(k0, k1);
- a.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- b.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- c.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- d.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- e.iter_bytes(true, |bytes| {
- s.input(bytes);
- true
- });
- s.result_u64()
-}
-
-#[inline]
-pub fn default_state() -> State {
- State::new(0, 0)
-}
-
-struct SipState {
- k0: u64,
- k1: u64,
- length: uint, // how many bytes we've processed
- v0: u64, // hash state
- v1: u64,
- v2: u64,
- v3: u64,
- tail: [u8, ..8], // unprocessed bytes
- ntail: uint, // how many bytes in tail are valid
-}
-
-impl SipState {
- #[inline]
- fn new(key0: u64, key1: u64) -> SipState {
- let mut state = SipState {
- k0: key0,
- k1: key1,
- length: 0,
- v0: 0,
- v1: 0,
- v2: 0,
- v3: 0,
- tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ],
- ntail: 0,
- };
- state.reset();
- state
- }
-}
-
-// sadly, these macro definitions can't appear later,
-// because they're needed in the following defs;
-// this design could be improved.
-
-macro_rules! u8to64_le (
- ($buf:expr, $i:expr) =>
- ($buf[0+$i] as u64 |
- $buf[1+$i] as u64 << 8 |
- $buf[2+$i] as u64 << 16 |
- $buf[3+$i] as u64 << 24 |
- $buf[4+$i] as u64 << 32 |
- $buf[5+$i] as u64 << 40 |
- $buf[6+$i] as u64 << 48 |
- $buf[7+$i] as u64 << 56)
-)
-
-macro_rules! rotl (
- ($x:expr, $b:expr) =>
- (($x << $b) | ($x >> (64 - $b)))
-)
-
-macro_rules! compress (
- ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
- ({
- $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
- $v0 = rotl!($v0, 32);
- $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
- $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
- $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
- $v2 = rotl!($v2, 32);
- })
-)
-
-
-impl Writer for SipState {
- // Methods for io::writer
- #[inline]
- fn write(&mut self, msg: &[u8]) {
- let length = msg.len();
- self.length += length;
-
- let mut needed = 0u;
-
- if self.ntail != 0 {
- needed = 8 - self.ntail;
-
- if length < needed {
- let mut t = 0;
- while t < length {
- self.tail[self.ntail+t] = msg[t];
- t += 1;
- }
- self.ntail += length;
- return;
- }
-
- let mut t = 0;
- while t < needed {
- self.tail[self.ntail+t] = msg[t];
- t += 1;
- }
-
- let m = u8to64_le!(self.tail, 0);
-
- self.v3 ^= m;
- compress!(self.v0, self.v1, self.v2, self.v3);
- compress!(self.v0, self.v1, self.v2, self.v3);
- self.v0 ^= m;
-
- self.ntail = 0;
- }
-
- // Buffered tail is now flushed, process new input.
- let len = length - needed;
- let end = len & (!0x7);
- let left = len & 0x7;
-
- let mut i = needed;
- while i < end {
- let mi = u8to64_le!(msg, i);
-
- self.v3 ^= mi;
- compress!(self.v0, self.v1, self.v2, self.v3);
- compress!(self.v0, self.v1, self.v2, self.v3);
- self.v0 ^= mi;
-
- i += 8;
- }
-
- let mut t = 0u;
- while t < left {
- self.tail[t] = msg[i+t];
- t += 1
- }
- self.ntail = left;
- }
-
- fn flush(&mut self) {
- // No-op
- }
-}
-
-impl Streaming for SipState {
- #[inline]
- fn input(&mut self, buf: &[u8]) {
- self.write(buf);
- }
-
- #[inline]
- fn result_u64(&mut self) -> u64 {
- let mut v0 = self.v0;
- let mut v1 = self.v1;
- let mut v2 = self.v2;
- let mut v3 = self.v3;
-
- let mut b : u64 = (self.length as u64 & 0xff) << 56;
-
- if self.ntail > 0 { b |= self.tail[0] as u64 << 0; }
- if self.ntail > 1 { b |= self.tail[1] as u64 << 8; }
- if self.ntail > 2 { b |= self.tail[2] as u64 << 16; }
- if self.ntail > 3 { b |= self.tail[3] as u64 << 24; }
- if self.ntail > 4 { b |= self.tail[4] as u64 << 32; }
- if self.ntail > 5 { b |= self.tail[5] as u64 << 40; }
- if self.ntail > 6 { b |= self.tail[6] as u64 << 48; }
-
- v3 ^= b;
- compress!(v0, v1, v2, v3);
- compress!(v0, v1, v2, v3);
- v0 ^= b;
-
- v2 ^= 0xff;
- compress!(v0, v1, v2, v3);
- compress!(v0, v1, v2, v3);
- compress!(v0, v1, v2, v3);
- compress!(v0, v1, v2, v3);
-
- return (v0 ^ v1 ^ v2 ^ v3);
- }
-
- fn result_bytes(&mut self) -> ~[u8] {
- let h = self.result_u64();
- ~[(h >> 0) as u8,
- (h >> 8) as u8,
- (h >> 16) as u8,
- (h >> 24) as u8,
- (h >> 32) as u8,
- (h >> 40) as u8,
- (h >> 48) as u8,
- (h >> 56) as u8,
- ]
- }
-
- fn result_str(&mut self) -> ~str {
- let r = self.result_bytes();
- let mut s = ~"";
- for b in r.iter() {
- s.push_str((*b as uint).to_str_radix(16u));
- }
- s
- }
-
- #[inline]
- fn reset(&mut self) {
- self.length = 0;
- self.v0 = self.k0 ^ 0x736f6d6570736575;
- self.v1 = self.k1 ^ 0x646f72616e646f6d;
- self.v2 = self.k0 ^ 0x6c7967656e657261;
- self.v3 = self.k1 ^ 0x7465646279746573;
- self.ntail = 0;
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use prelude::*;
-
- // Hash just the bytes of the slice, without length prefix
- struct Bytes<'self>(&'self [u8]);
- impl<'self> IterBytes for Bytes<'self> {
- fn iter_bytes(&self, _lsb0: bool, f: |&[u8]| -> bool) -> bool {
- f(**self)
- }
- }
-
- #[test]
- fn test_siphash() {
- let vecs : [[u8, ..8], ..64] = [
- [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
- [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
- [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
- [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
- [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
- [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
- [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
- [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
- [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
- [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
- [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
- [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
- [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
- [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
- [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
- [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
- [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
- [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
- [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
- [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
- [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
- [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
- [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
- [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
- [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
- [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
- [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
- [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
- [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
- [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
- [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
- [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
- [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
- [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
- [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
- [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
- [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
- [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
- [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
- [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
- [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
- [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
- [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
- [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
- [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
- [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
- [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
- [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
- [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
- [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
- [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
- [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
- [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
- [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
- [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
- [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
- [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
- [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
- [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
- [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
- [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
- [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
- [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
- [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
- ];
-
- let k0 = 0x_07_06_05_04_03_02_01_00_u64;
- let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
- let mut buf : ~[u8] = ~[];
- let mut t = 0;
- let mut stream_inc = SipState::new(k0, k1);
- let mut stream_full = SipState::new(k0, k1);
-
- fn to_hex_str(r: &[u8, ..8]) -> ~str {
- let mut s = ~"";
- for b in r.iter() {
- s.push_str((*b as uint).to_str_radix(16u));
- }
- s
- }
-
- while t < 64 {
- debug!("siphash test {}", t);
- let vec = u8to64_le!(vecs[t], 0);
- let out = Bytes(buf.as_slice()).hash_keyed(k0, k1);
- debug!("got {:?}, expected {:?}", out, vec);
- assert_eq!(vec, out);
-
- stream_full.reset();
- stream_full.input(buf);
- let f = stream_full.result_str();
- let i = stream_inc.result_str();
- let v = to_hex_str(&vecs[t]);
- debug!("{}: ({}) => inc={} full={}", t, v, i, f);
-
- assert!(f == i && f == v);
-
- buf.push(t as u8);
- stream_inc.input([t as u8]);
-
- t += 1;
- }
- }
-
- #[test] #[cfg(target_arch = "arm")]
- fn test_hash_uint() {
- let val = 0xdeadbeef_deadbeef_u64;
- assert!((val as u64).hash() != (val as uint).hash());
- assert_eq!((val as u32).hash(), (val as uint).hash());
- }
- #[test] #[cfg(target_arch = "x86_64")]
- fn test_hash_uint() {
- let val = 0xdeadbeef_deadbeef_u64;
- assert_eq!((val as u64).hash(), (val as uint).hash());
- assert!((val as u32).hash() != (val as uint).hash());
- }
- #[test] #[cfg(target_arch = "x86")]
- fn test_hash_uint() {
- let val = 0xdeadbeef_deadbeef_u64;
- assert!((val as u64).hash() != (val as uint).hash());
- assert_eq!((val as u32).hash(), (val as uint).hash());
- }
-
- #[test]
- fn test_hash_idempotent() {
- let val64 = 0xdeadbeef_deadbeef_u64;
- val64.hash() == val64.hash();
- let val32 = 0xdeadbeef_u32;
- val32.hash() == val32.hash();
- }
-
- #[test]
- fn test_hash_no_bytes_dropped_64() {
- let val = 0xdeadbeef_deadbeef_u64;
-
- assert!(val.hash() != zero_byte(val, 0).hash());
- assert!(val.hash() != zero_byte(val, 1).hash());
- assert!(val.hash() != zero_byte(val, 2).hash());
- assert!(val.hash() != zero_byte(val, 3).hash());
- assert!(val.hash() != zero_byte(val, 4).hash());
- assert!(val.hash() != zero_byte(val, 5).hash());
- assert!(val.hash() != zero_byte(val, 6).hash());
- assert!(val.hash() != zero_byte(val, 7).hash());
-
- fn zero_byte(val: u64, byte: uint) -> u64 {
- assert!(byte < 8);
- val & !(0xff << (byte * 8))
- }
- }
-
- #[test]
- fn test_hash_no_bytes_dropped_32() {
- let val = 0xdeadbeef_u32;
-
- assert!(val.hash() != zero_byte(val, 0).hash());
- assert!(val.hash() != zero_byte(val, 1).hash());
- assert!(val.hash() != zero_byte(val, 2).hash());
- assert!(val.hash() != zero_byte(val, 3).hash());
-
- fn zero_byte(val: u32, byte: uint) -> u32 {
- assert!(byte < 4);
- val & !(0xff << (byte * 8))
- }
- }
-
- #[test]
- fn test_float_hashes_differ() {
- assert!(0.0.hash() != 1.0.hash());
- assert!(1.0.hash() != (-1.0).hash());
- }
-
- #[test]
- fn test_float_hashes_of_zero() {
- assert_eq!(0.0.hash(), (-0.0).hash());
- }
-
- #[test]
- fn test_hash_no_concat_alias() {
- let s = ("aa", "bb");
- let t = ("aabb", "");
- let u = ("a", "abb");
-
- let v = (&[1u8], &[0u8, 0], &[0u8]);
- let w = (&[1u8, 0, 0, 0], &[], &[]);
-
- assert!(v != w);
- assert!(s.hash() != t.hash() && s.hash() != u.hash());
- assert!(v.hash() != w.hash());
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! An unordered map and set type implemented as hash tables
-//!
-//! The tables use a keyed hash with new random keys generated for each container, so the ordering
-//! of a set of keys in a hash table is randomized.
-
-use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
-use clone::Clone;
-use cmp::{Eq, Equiv};
-use default::Default;
-use hash::Hash;
-use iter::{Iterator, FromIterator, Extendable};
-use iter::{FilterMap, Chain, Repeat, Zip};
-use num;
-use option::{None, Option, Some};
-use rand::Rng;
-use rand;
-use uint;
-use util::replace;
-use vec::{ImmutableVector, MutableVector, OwnedVector};
-use vec;
-
-static INITIAL_CAPACITY: uint = 32u; // 2^5
-
-struct Bucket<K,V> {
- hash: uint,
- key: K,
- value: V,
-}
-
-/// A hash map implementation which uses linear probing along with the SipHash
-/// hash function for internal state. This means that the order of all hash maps
-/// is randomized by keying each hash map randomly on creation.
-///
-/// It is required that the keys implement the `Eq` and `Hash` traits, although
-/// this can frequently be achieved by just implementing the `Eq` and
-/// `IterBytes` traits as `Hash` is automatically implemented for types that
-/// implement `IterBytes`.
-pub struct HashMap<K,V> {
- priv k0: u64,
- priv k1: u64,
- priv resize_at: uint,
- priv size: uint,
- priv buckets: ~[Option<Bucket<K, V>>],
-}
-
-// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
-// which would be nifty
-enum SearchResult {
- FoundEntry(uint), FoundHole(uint), TableFull
-}
-
-#[inline]
-fn resize_at(capacity: uint) -> uint {
- (capacity * 3) / 4
-}
-
-impl<K:Hash + Eq,V> HashMap<K, V> {
- #[inline]
- fn to_bucket(&self, h: uint) -> uint {
- // A good hash function with entropy spread over all of the
- // bits is assumed. SipHash is more than good enough.
- h % self.buckets.len()
- }
-
- #[inline]
- fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint {
- (idx + 1) % len_buckets
- }
-
- #[inline]
- fn bucket_sequence(&self, hash: uint, op: |uint| -> bool) -> bool {
- let start_idx = self.to_bucket(hash);
- let len_buckets = self.buckets.len();
- let mut idx = start_idx;
- loop {
- if !op(idx) { return false; }
- idx = self.next_bucket(idx, len_buckets);
- if idx == start_idx {
- return true;
- }
- }
- }
-
- #[inline]
- fn bucket_for_key(&self, k: &K) -> SearchResult {
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.bucket_for_key_with_hash(hash, k)
- }
-
- #[inline]
- fn bucket_for_key_equiv<Q:Hash + Equiv<K>>(&self, k: &Q)
- -> SearchResult {
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.bucket_for_key_with_hash_equiv(hash, k)
- }
-
- #[inline]
- fn bucket_for_key_with_hash(&self,
- hash: uint,
- k: &K)
- -> SearchResult {
- let mut ret = TableFull;
- self.bucket_sequence(hash, |i| {
- match self.buckets[i] {
- Some(ref bkt) if bkt.hash == hash && *k == bkt.key => {
- ret = FoundEntry(i); false
- },
- None => { ret = FoundHole(i); false }
- _ => true,
- }
- });
- ret
- }
-
- #[inline]
- fn bucket_for_key_with_hash_equiv<Q:Equiv<K>>(&self,
- hash: uint,
- k: &Q)
- -> SearchResult {
- let mut ret = TableFull;
- self.bucket_sequence(hash, |i| {
- match self.buckets[i] {
- Some(ref bkt) if bkt.hash == hash && k.equiv(&bkt.key) => {
- ret = FoundEntry(i); false
- },
- None => { ret = FoundHole(i); false }
- _ => true,
- }
- });
- ret
- }
-
- /// Expand the capacity of the array to the next power of two
- /// and re-insert each of the existing buckets.
- #[inline]
- fn expand(&mut self) {
- let new_capacity = self.buckets.len() * 2;
- self.resize(new_capacity);
- }
-
- /// Expands the capacity of the array and re-insert each of the
- /// existing buckets.
- fn resize(&mut self, new_capacity: uint) {
- self.resize_at = resize_at(new_capacity);
-
- let old_buckets = replace(&mut self.buckets,
- vec::from_fn(new_capacity, |_| None));
-
- self.size = 0;
- // move_rev_iter is more efficient
- for bucket in old_buckets.move_rev_iter() {
- self.insert_opt_bucket(bucket);
- }
- }
-
- fn insert_opt_bucket(&mut self, bucket: Option<Bucket<K, V>>) {
- match bucket {
- Some(Bucket{hash: hash, key: key, value: value}) => {
- self.insert_internal(hash, key, value);
- }
- None => {}
- }
- }
-
- #[inline]
- fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
- match self.buckets[idx] {
- Some(ref bkt) => &bkt.value,
- None => fail!("HashMap::find: internal logic error"),
- }
- }
-
- #[inline]
- fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
- match self.buckets[idx] {
- Some(ref mut bkt) => &mut bkt.value,
- None => unreachable!()
- }
- }
-
- /// Inserts the key value pair into the buckets.
- /// Assumes that there will be a bucket.
- /// True if there was no previous entry with that key
- fn insert_internal(&mut self, hash: uint, k: K, v: V) -> Option<V> {
- match self.bucket_for_key_with_hash(hash, &k) {
- TableFull => { fail!("Internal logic error"); }
- FoundHole(idx) => {
- self.buckets[idx] = Some(Bucket{hash: hash, key: k,
- value: v});
- self.size += 1;
- None
- }
- FoundEntry(idx) => {
- match self.buckets[idx] {
- None => { fail!("insert_internal: Internal logic error") }
- Some(ref mut b) => {
- b.hash = hash;
- b.key = k;
- Some(replace(&mut b.value, v))
- }
- }
- }
- }
- }
-
- fn pop_internal(&mut self, hash: uint, k: &K) -> Option<V> {
- // Removing from an open-addressed hashtable
- // is, well, painful. The problem is that
- // the entry may lie on the probe path for other
- // entries, so removing it would make you think that
- // those probe paths are empty.
- //
- // To address this we basically have to keep walking,
- // re-inserting entries we find until we reach an empty
- // bucket. We know we will eventually reach one because
- // we insert one ourselves at the beginning (the removed
- // entry).
- //
- // I found this explanation elucidating:
- // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf
- let mut idx = match self.bucket_for_key_with_hash(hash, k) {
- TableFull | FoundHole(_) => return None,
- FoundEntry(idx) => idx
- };
-
- let len_buckets = self.buckets.len();
- let bucket = self.buckets[idx].take();
-
- let value = bucket.map(|bucket| bucket.value);
-
- /* re-inserting buckets may cause changes in size, so remember
- what our new size is ahead of time before we start insertions */
- let size = self.size - 1;
- idx = self.next_bucket(idx, len_buckets);
- while self.buckets[idx].is_some() {
- let bucket = self.buckets[idx].take();
- self.insert_opt_bucket(bucket);
- idx = self.next_bucket(idx, len_buckets);
- }
- self.size = size;
-
- value
- }
-}
-
-impl<K:Hash + Eq,V> Container for HashMap<K, V> {
- /// Return the number of elements in the map
- fn len(&self) -> uint { self.size }
-}
-
-impl<K:Hash + Eq,V> Mutable for HashMap<K, V> {
- /// Clear the map, removing all key-value pairs.
- fn clear(&mut self) {
- for bkt in self.buckets.mut_iter() {
- *bkt = None;
- }
- self.size = 0;
- }
-}
-
-impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
- /// Return a reference to the value corresponding to the key
- fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
- match self.bucket_for_key(k) {
- FoundEntry(idx) => Some(self.value_for_bucket(idx)),
- TableFull | FoundHole(_) => None,
- }
- }
-}
-
-impl<K:Hash + Eq,V> MutableMap<K, V> for HashMap<K, V> {
- /// Return a mutable reference to the value corresponding to the key
- fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
- let idx = match self.bucket_for_key(k) {
- FoundEntry(idx) => idx,
- TableFull | FoundHole(_) => return None
- };
- Some(self.mut_value_for_bucket(idx))
- }
-
- /// Insert a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise None is returned.
- fn swap(&mut self, k: K, v: V) -> Option<V> {
- // this could be faster.
-
- if self.size >= self.resize_at {
- // n.b.: We could also do this after searching, so
- // that we do not resize if this call to insert is
- // simply going to update a key in place. My sense
- // though is that it's worse to have to search through
- // buckets to find the right spot twice than to just
- // resize in this corner case.
- self.expand();
- }
-
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.insert_internal(hash, k, v)
- }
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- fn pop(&mut self, k: &K) -> Option<V> {
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.pop_internal(hash, k)
- }
-}
-
-impl<K: Hash + Eq, V> HashMap<K, V> {
- /// Create an empty HashMap
- pub fn new() -> HashMap<K, V> {
- HashMap::with_capacity(INITIAL_CAPACITY)
- }
-
- /// Create an empty HashMap with space for at least `capacity`
- /// elements in the hash table.
- pub fn with_capacity(capacity: uint) -> HashMap<K, V> {
- let mut r = rand::task_rng();
- HashMap::with_capacity_and_keys(r.gen(), r.gen(), capacity)
- }
-
- /// Create an empty HashMap with space for at least `capacity`
- /// elements, using `k0` and `k1` as the keys.
- ///
- /// Warning: `k0` and `k1` are normally randomly generated, and
- /// are designed to allow HashMaps to be resistant to attacks that
- /// cause many collisions and very poor performance. Setting them
- /// manually using this function can expose a DoS attack vector.
- pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashMap<K, V> {
- let cap = num::max(INITIAL_CAPACITY, capacity);
- HashMap {
- k0: k0, k1: k1,
- resize_at: resize_at(cap),
- size: 0,
- buckets: vec::from_fn(cap, |_| None)
- }
- }
-
- /// Reserve space for at least `n` elements in the hash table.
- pub fn reserve_at_least(&mut self, n: uint) {
- if n > self.buckets.len() {
- let buckets = n * 4 / 3 + 1;
- self.resize(uint::next_power_of_two(buckets));
- }
- }
-
- /// Modify and return the value corresponding to the key in the map, or
- /// insert and return a new value if it doesn't exist.
- pub fn mangle<'a,
- A>(
- &'a mut self,
- k: K,
- a: A,
- not_found: |&K, A| -> V,
- found: |&K, &mut V, A|)
- -> &'a mut V {
- if self.size >= self.resize_at {
- // n.b.: We could also do this after searching, so
- // that we do not resize if this call to insert is
- // simply going to update a key in place. My sense
- // though is that it's worse to have to search through
- // buckets to find the right spot twice than to just
- // resize in this corner case.
- self.expand();
- }
-
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- let idx = match self.bucket_for_key_with_hash(hash, &k) {
- TableFull => fail!("Internal logic error"),
- FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
- FoundHole(idx) => {
- let v = not_found(&k, a);
- self.buckets[idx] = Some(Bucket{hash: hash, key: k, value: v});
- self.size += 1;
- idx
- }
- };
-
- self.mut_value_for_bucket(idx)
- }
-
- /// Return the value corresponding to the key in the map, or insert
- /// and return the value if it doesn't exist.
- pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
- self.mangle(k, v, |_k, a| a, |_k,_v,_a| ())
- }
-
- /// Return the value corresponding to the key in the map, or create,
- /// insert, and return a new value if it doesn't exist.
- pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: |&K| -> V)
- -> &'a mut V {
- self.mangle(k, (), |k,_a| f(k), |_k,_v,_a| ())
- }
-
- /// Insert a key-value pair into the map if the key is not already present.
- /// Otherwise, modify the existing value for the key.
- /// Returns the new or modified value for the key.
- pub fn insert_or_update_with<'a>(
- &'a mut self,
- k: K,
- v: V,
- f: |&K, &mut V|)
- -> &'a mut V {
- self.mangle(k, v, |_k,a| a, |k,v,_a| f(k,v))
- }
-
- /// Retrieves a value for the given key, failing if the key is not
- /// present.
- pub fn get<'a>(&'a self, k: &K) -> &'a V {
- match self.find(k) {
- Some(v) => v,
- None => fail!("No entry found for key: {:?}", k),
- }
- }
-
- /// Retrieves a (mutable) value for the given key, failing if the key
- /// is not present.
- pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
- match self.find_mut(k) {
- Some(v) => v,
- None => fail!("No entry found for key: {:?}", k),
- }
- }
-
- /// Return true if the map contains a value for the specified key,
- /// using equivalence
- pub fn contains_key_equiv<Q:Hash + Equiv<K>>(&self, key: &Q) -> bool {
- match self.bucket_for_key_equiv(key) {
- FoundEntry(_) => {true}
- TableFull | FoundHole(_) => {false}
- }
- }
-
- /// Return the value corresponding to the key in the map, using
- /// equivalence
- pub fn find_equiv<'a, Q:Hash + Equiv<K>>(&'a self, k: &Q)
- -> Option<&'a V> {
- match self.bucket_for_key_equiv(k) {
- FoundEntry(idx) => Some(self.value_for_bucket(idx)),
- TableFull | FoundHole(_) => None,
- }
- }
-
- /// Visit all keys
- pub fn each_key(&self, blk: |k: &K| -> bool) -> bool {
- self.iter().advance(|(k, _)| blk(k))
- }
-
- /// Visit all values
- pub fn each_value<'a>(&'a self, blk: |v: &'a V| -> bool) -> bool {
- self.iter().advance(|(_, v)| blk(v))
- }
-
- /// An iterator visiting all key-value pairs in arbitrary order.
- /// Iterator element type is (&'a K, &'a V).
- pub fn iter<'a>(&'a self) -> HashMapIterator<'a, K, V> {
- HashMapIterator { iter: self.buckets.iter() }
- }
-
- /// An iterator visiting all key-value pairs in arbitrary order,
- /// with mutable references to the values.
- /// Iterator element type is (&'a K, &'a mut V).
- pub fn mut_iter<'a>(&'a mut self) -> HashMapMutIterator<'a, K, V> {
- HashMapMutIterator { iter: self.buckets.mut_iter() }
- }
-
- /// Creates a consuming iterator, that is, one that moves each key-value
- /// pair out of the map in arbitrary order. The map cannot be used after
- /// calling this.
- pub fn move_iter(self) -> HashMapMoveIterator<K, V> {
- // `move_rev_iter` is more efficient than `move_iter` for vectors
- HashMapMoveIterator {iter: self.buckets.move_rev_iter()}
- }
-}
-
-impl<K: Hash + Eq, V: Clone> HashMap<K, V> {
- /// Like `find`, but returns a copy of the value.
- pub fn find_copy(&self, k: &K) -> Option<V> {
- self.find(k).map(|v| (*v).clone())
- }
-
- /// Like `get`, but returns a copy of the value.
- pub fn get_copy(&self, k: &K) -> V {
- (*self.get(k)).clone()
- }
-}
-
-impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
- fn eq(&self, other: &HashMap<K, V>) -> bool {
- if self.len() != other.len() { return false; }
-
- self.iter().all(|(key, value)| {
- match other.find(key) {
- None => false,
- Some(v) => value == v
- }
- })
- }
-
- fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
-}
-
-impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
- fn clone(&self) -> HashMap<K,V> {
- let mut new_map = HashMap::with_capacity(self.len());
- for (key, value) in self.iter() {
- new_map.insert((*key).clone(), (*value).clone());
- }
- new_map
- }
-}
-
-/// HashMap iterator
-#[deriving(Clone)]
-pub struct HashMapIterator<'self, K, V> {
- priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
-}
-
-/// HashMap mutable values iterator
-pub struct HashMapMutIterator<'self, K, V> {
- priv iter: vec::VecMutIterator<'self, Option<Bucket<K, V>>>,
-}
-
-/// HashMap move iterator
-pub struct HashMapMoveIterator<K, V> {
- priv iter: vec::MoveRevIterator<Option<Bucket<K, V>>>,
-}
-
-/// HashSet iterator
-#[deriving(Clone)]
-pub struct HashSetIterator<'self, K> {
- priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>,
-}
-
-/// HashSet move iterator
-pub struct HashSetMoveIterator<K> {
- priv iter: vec::MoveRevIterator<Option<Bucket<K, ()>>>,
-}
-
-impl<'self, K, V> Iterator<(&'self K, &'self V)> for HashMapIterator<'self, K, V> {
- #[inline]
- fn next(&mut self) -> Option<(&'self K, &'self V)> {
- for elt in self.iter {
- match elt {
- &Some(ref bucket) => return Some((&bucket.key, &bucket.value)),
- &None => {},
- }
- }
- None
- }
-}
-
-impl<'self, K, V> Iterator<(&'self K, &'self mut V)> for HashMapMutIterator<'self, K, V> {
- #[inline]
- fn next(&mut self) -> Option<(&'self K, &'self mut V)> {
- for elt in self.iter {
- match elt {
- &Some(ref mut bucket) => return Some((&bucket.key, &mut bucket.value)),
- &None => {},
- }
- }
- None
- }
-}
-
-impl<K, V> Iterator<(K, V)> for HashMapMoveIterator<K, V> {
- #[inline]
- fn next(&mut self) -> Option<(K, V)> {
- for elt in self.iter {
- match elt {
- Some(Bucket {key, value, ..}) => return Some((key, value)),
- None => {},
- }
- }
- None
- }
-}
-
-impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> {
- #[inline]
- fn next(&mut self) -> Option<&'self K> {
- for elt in self.iter {
- match elt {
- &Some(ref bucket) => return Some(&bucket.key),
- &None => {},
- }
- }
- None
- }
-}
-
-impl<K> Iterator<K> for HashSetMoveIterator<K> {
- #[inline]
- fn next(&mut self) -> Option<K> {
- for elt in self.iter {
- match elt {
- Some(bucket) => return Some(bucket.key),
- None => {},
- }
- }
- None
- }
-}
-
-impl<K: Eq + Hash, V> FromIterator<(K, V)> for HashMap<K, V> {
- fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V> {
- let (lower, _) = iter.size_hint();
- let mut map = HashMap::with_capacity(lower);
- map.extend(iter);
- map
- }
-}
-
-impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
- fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
- for (k, v) in *iter {
- self.insert(k, v);
- }
- }
-}
-
-impl<K: Eq + Hash, V> Default for HashMap<K, V> {
- fn default() -> HashMap<K, V> { HashMap::new() }
-}
-
-/// An implementation of a hash set using the underlying representation of a
-/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
-/// requires that the elements implement the `Eq` and `Hash` traits.
-pub struct HashSet<T> {
- priv map: HashMap<T, ()>
-}
-
-impl<T:Hash + Eq> Eq for HashSet<T> {
- fn eq(&self, other: &HashSet<T>) -> bool { self.map == other.map }
- fn ne(&self, other: &HashSet<T>) -> bool { self.map != other.map }
-}
-
-impl<T:Hash + Eq> Container for HashSet<T> {
- /// Return the number of elements in the set
- fn len(&self) -> uint { self.map.len() }
-}
-
-impl<T:Hash + Eq> Mutable for HashSet<T> {
- /// Clear the set, removing all values.
- fn clear(&mut self) { self.map.clear() }
-}
-
-impl<T:Hash + Eq> Set<T> for HashSet<T> {
- /// Return true if the set contains a value
- fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
-
- /// Return true if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- fn is_disjoint(&self, other: &HashSet<T>) -> bool {
- self.iter().all(|v| !other.contains(v))
- }
-
- /// Return true if the set is a subset of another
- fn is_subset(&self, other: &HashSet<T>) -> bool {
- self.iter().all(|v| other.contains(v))
- }
-
- /// Return true if the set is a superset of another
- fn is_superset(&self, other: &HashSet<T>) -> bool {
- other.is_subset(self)
- }
-}
-
-impl<T:Hash + Eq> MutableSet<T> for HashSet<T> {
- /// Add a value to the set. Return true if the value was not already
- /// present in the set.
- fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
-
- /// Remove a value from the set. Return true if the value was
- /// present in the set.
- fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
-}
-
-impl<T:Hash + Eq> HashSet<T> {
- /// Create an empty HashSet
- pub fn new() -> HashSet<T> {
- HashSet::with_capacity(INITIAL_CAPACITY)
- }
-
- /// Create an empty HashSet with space for at least `n` elements in
- /// the hash table.
- pub fn with_capacity(capacity: uint) -> HashSet<T> {
- HashSet { map: HashMap::with_capacity(capacity) }
- }
-
- /// Create an empty HashSet with space for at least `capacity`
- /// elements in the hash table, using `k0` and `k1` as the keys.
- ///
- /// Warning: `k0` and `k1` are normally randomly generated, and
- /// are designed to allow HashSets to be resistant to attacks that
- /// cause many collisions and very poor performance. Setting them
- /// manually using this function can expose a DoS attack vector.
- pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashSet<T> {
- HashSet { map: HashMap::with_capacity_and_keys(k0, k1, capacity) }
- }
-
- /// Reserve space for at least `n` elements in the hash table.
- pub fn reserve_at_least(&mut self, n: uint) {
- self.map.reserve_at_least(n)
- }
-
- /// Returns true if the hash set contains a value equivalent to the
- /// given query value.
- pub fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
- self.map.contains_key_equiv(value)
- }
-
- /// An iterator visiting all elements in arbitrary order.
- /// Iterator element type is &'a T.
- pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> {
- HashSetIterator { iter: self.map.buckets.iter() }
- }
-
- /// Creates a consuming iterator, that is, one that moves each value out
- /// of the set in arbitrary order. The set cannot be used after calling
- /// this.
- pub fn move_iter(self) -> HashSetMoveIterator<T> {
- // `move_rev_iter` is more efficient than `move_iter` for vectors
- HashSetMoveIterator {iter: self.map.buckets.move_rev_iter()}
- }
-
- /// Visit the values representing the difference
- pub fn difference<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> {
- Repeat::new(other)
- .zip(self.iter())
- .filter_map(|(other, elt)| {
- if !other.contains(elt) { Some(elt) } else { None }
- })
- }
-
- /// Visit the values representing the symmetric difference
- pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T>)
- -> Chain<SetAlgebraIter<'a, T>, SetAlgebraIter<'a, T>> {
- self.difference(other).chain(other.difference(self))
- }
-
- /// Visit the values representing the intersection
- pub fn intersection<'a>(&'a self, other: &'a HashSet<T>)
- -> SetAlgebraIter<'a, T> {
- Repeat::new(other)
- .zip(self.iter())
- .filter_map(|(other, elt)| {
- if other.contains(elt) { Some(elt) } else { None }
- })
- }
-
- /// Visit the values representing the union
- pub fn union<'a>(&'a self, other: &'a HashSet<T>)
- -> Chain<HashSetIterator<'a, T>, SetAlgebraIter<'a, T>> {
- self.iter().chain(other.difference(self))
- }
-
-}
-
-impl<T:Hash + Eq + Clone> Clone for HashSet<T> {
- fn clone(&self) -> HashSet<T> {
- HashSet {
- map: self.map.clone()
- }
- }
-}
-
-impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
- fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
- let (lower, _) = iter.size_hint();
- let mut set = HashSet::with_capacity(lower);
- set.extend(iter);
- set
- }
-}
-
-impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
- fn extend<T: Iterator<K>>(&mut self, iter: &mut T) {
- for k in *iter {
- self.insert(k);
- }
- }
-}
-
-impl<K: Eq + Hash> Default for HashSet<K> {
- fn default() -> HashSet<K> { HashSet::new() }
-}
-
-// `Repeat` is used to feed the filter closure an explicit capture
-// of a reference to the other set
-/// Set operations iterator
-pub type SetAlgebraIter<'self, T> =
- FilterMap<'static,(&'self HashSet<T>, &'self T), &'self T,
- Zip<Repeat<&'self HashSet<T>>,HashSetIterator<'self,T>>>;
-
-
-#[cfg(test)]
-mod test_map {
- use prelude::*;
- use super::*;
-
- #[test]
- fn test_create_capacity_zero() {
- let mut m = HashMap::with_capacity(0);
- assert!(m.insert(1, 1));
- }
-
- #[test]
- fn test_insert() {
- let mut m = HashMap::new();
- assert!(m.insert(1, 2));
- assert!(m.insert(2, 4));
- assert_eq!(*m.get(&1), 2);
- assert_eq!(*m.get(&2), 4);
- }
-
- #[test]
- fn test_find_mut() {
- let mut m = HashMap::new();
- assert!(m.insert(1, 12));
- assert!(m.insert(2, 8));
- assert!(m.insert(5, 14));
- let new = 100;
- match m.find_mut(&5) {
- None => fail!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_insert_overwrite() {
- let mut m = HashMap::new();
- assert!(m.insert(1, 2));
- assert_eq!(*m.get(&1), 2);
- assert!(!m.insert(1, 3));
- assert_eq!(*m.get(&1), 3);
- }
-
- #[test]
- fn test_insert_conflicts() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1, 2));
- assert!(m.insert(5, 3));
- assert!(m.insert(9, 4));
- assert_eq!(*m.get(&9), 4);
- assert_eq!(*m.get(&5), 3);
- assert_eq!(*m.get(&1), 2);
- }
-
- #[test]
- fn test_conflict_remove() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1, 2));
- assert!(m.insert(5, 3));
- assert!(m.insert(9, 4));
- assert!(m.remove(&1));
- assert_eq!(*m.get(&9), 4);
- assert_eq!(*m.get(&5), 3);
- }
-
- #[test]
- fn test_is_empty() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1, 2));
- assert!(!m.is_empty());
- assert!(m.remove(&1));
- assert!(m.is_empty());
- }
-
- #[test]
- fn test_pop() {
- let mut m = HashMap::new();
- m.insert(1, 2);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_swap() {
- let mut m = HashMap::new();
- assert_eq!(m.swap(1, 2), None);
- assert_eq!(m.swap(1, 3), Some(2));
- assert_eq!(m.swap(1, 4), Some(3));
- }
-
- #[test]
- fn test_find_or_insert() {
- let mut m: HashMap<int,int> = HashMap::new();
- assert_eq!(*m.find_or_insert(1, 2), 2);
- assert_eq!(*m.find_or_insert(1, 3), 2);
- }
-
- #[test]
- fn test_find_or_insert_with() {
- let mut m: HashMap<int,int> = HashMap::new();
- assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
- assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
- }
-
- #[test]
- fn test_insert_or_update_with() {
- let mut m: HashMap<int,int> = HashMap::new();
- assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
- assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
- }
-
- #[test]
- fn test_move_iter() {
- let hm = {
- let mut hm = HashMap::new();
-
- hm.insert('a', 1);
- hm.insert('b', 2);
-
- hm
- };
-
- let v = hm.move_iter().collect::<~[(char, int)]>();
- assert!([('a', 1), ('b', 2)] == v || [('b', 2), ('a', 1)] == v);
- }
-
- #[test]
- fn test_iterate() {
- let mut m = HashMap::with_capacity(4);
- for i in range(0u, 32) {
- assert!(m.insert(i, i*2));
- }
- let mut observed = 0;
- for (k, v) in m.iter() {
- assert_eq!(*v, *k * 2);
- observed |= (1 << *k);
- }
- assert_eq!(observed, 0xFFFF_FFFF);
- }
-
- #[test]
- fn test_find() {
- let mut m = HashMap::new();
- assert!(m.find(&1).is_none());
- m.insert(1, 2);
- match m.find(&1) {
- None => fail!(),
- Some(v) => assert!(*v == 2)
- }
- }
-
- #[test]
- fn test_eq() {
- let mut m1 = HashMap::new();
- m1.insert(1, 2);
- m1.insert(2, 3);
- m1.insert(3, 4);
-
- let mut m2 = HashMap::new();
- m2.insert(1, 2);
- m2.insert(2, 3);
-
- assert!(m1 != m2);
-
- m2.insert(3, 4);
-
- assert_eq!(m1, m2);
- }
-
- #[test]
- fn test_expand() {
- let mut m = HashMap::new();
-
- assert_eq!(m.len(), 0);
- assert!(m.is_empty());
-
- let mut i = 0u;
- let old_resize_at = m.resize_at;
- while old_resize_at == m.resize_at {
- m.insert(i, i);
- i += 1;
- }
-
- assert_eq!(m.len(), i);
- assert!(!m.is_empty());
- }
-
- #[test]
- fn test_find_equiv() {
- let mut m = HashMap::new();
-
- let (foo, bar, baz) = (1,2,3);
- m.insert(~"foo", foo);
- m.insert(~"bar", bar);
- m.insert(~"baz", baz);
-
-
- assert_eq!(m.find_equiv(&("foo")), Some(&foo));
- assert_eq!(m.find_equiv(&("bar")), Some(&bar));
- assert_eq!(m.find_equiv(&("baz")), Some(&baz));
-
- assert_eq!(m.find_equiv(&("qux")), None);
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-}
-
-#[cfg(test)]
-mod test_set {
- use super::*;
- use prelude::*;
- use container::Container;
- use vec::ImmutableEqVector;
-
- #[test]
- fn test_disjoint() {
- let mut xs = HashSet::new();
- let mut ys = HashSet::new();
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(5));
- assert!(ys.insert(11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(7));
- assert!(xs.insert(19));
- assert!(xs.insert(4));
- assert!(ys.insert(2));
- assert!(ys.insert(-11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(ys.insert(7));
- assert!(!xs.is_disjoint(&ys));
- assert!(!ys.is_disjoint(&xs));
- }
-
- #[test]
- fn test_subset_and_superset() {
- let mut a = HashSet::new();
- assert!(a.insert(0));
- assert!(a.insert(5));
- assert!(a.insert(11));
- assert!(a.insert(7));
-
- let mut b = HashSet::new();
- assert!(b.insert(0));
- assert!(b.insert(7));
- assert!(b.insert(19));
- assert!(b.insert(250));
- assert!(b.insert(11));
- assert!(b.insert(200));
-
- assert!(!a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(!b.is_superset(&a));
-
- assert!(b.insert(5));
-
- assert!(a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(b.is_superset(&a));
- }
-
- #[test]
- fn test_iterate() {
- let mut a = HashSet::new();
- for i in range(0u, 32) {
- assert!(a.insert(i));
- }
- let mut observed = 0;
- for k in a.iter() {
- observed |= (1 << *k);
- }
- assert_eq!(observed, 0xFFFF_FFFF);
- }
-
- #[test]
- fn test_intersection() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(11));
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(77));
- assert!(a.insert(103));
- assert!(a.insert(5));
- assert!(a.insert(-5));
-
- assert!(b.insert(2));
- assert!(b.insert(11));
- assert!(b.insert(77));
- assert!(b.insert(-9));
- assert!(b.insert(-42));
- assert!(b.insert(5));
- assert!(b.insert(3));
-
- let mut i = 0;
- let expected = [3, 5, 11, 77];
- for x in a.intersection(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_difference() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(3));
- assert!(b.insert(9));
-
- let mut i = 0;
- let expected = [1, 5, 11];
- for x in a.difference(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_symmetric_difference() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(-2));
- assert!(b.insert(3));
- assert!(b.insert(9));
- assert!(b.insert(14));
- assert!(b.insert(22));
-
- let mut i = 0;
- let expected = [-2, 1, 5, 11, 14, 22];
- for x in a.symmetric_difference(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_union() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
- assert!(a.insert(16));
- assert!(a.insert(19));
- assert!(a.insert(24));
-
- assert!(b.insert(-2));
- assert!(b.insert(1));
- assert!(b.insert(5));
- assert!(b.insert(9));
- assert!(b.insert(13));
- assert!(b.insert(19));
-
- let mut i = 0;
- let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
- for x in a.union(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9];
-
- let set: HashSet<int> = xs.iter().map(|&x| x).collect();
-
- for x in xs.iter() {
- assert!(set.contains(x));
- }
- }
-
- #[test]
- fn test_move_iter() {
- let hs = {
- let mut hs = HashSet::new();
-
- hs.insert('a');
- hs.insert('b');
-
- hs
- };
-
- let v = hs.move_iter().collect::<~[char]>();
- assert!(['a', 'b'] == v || ['b', 'a'] == v);
- }
-
- #[test]
- fn test_eq() {
- let mut s1 = HashSet::new();
- s1.insert(1);
- s1.insert(2);
- s1.insert(3);
-
- let mut s2 = HashSet::new();
- s2.insert(1);
- s2.insert(2);
-
- assert!(s1 != s2);
-
- s2.insert(3);
-
- assert_eq!(s1, s2);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Buffering wrappers for I/O traits
-//!
-//! It can be excessively inefficient to work directly with a `Reader` or
-//! `Writer`. Every call to `read` or `write` on `TcpStream` results in a
-//! system call, for example. This module provides structures that wrap
-//! `Readers`, `Writers`, and `Streams` and buffer input and output to them.
-//!
-//! # Examples
-//!
-//! ```
-//! let tcp_stream = TcpStream::connect(addr);
-//! let reader = BufferedReader::new(tcp_stream);
-//!
-//! let mut buf: ~[u8] = vec::from_elem(100, 0u8);
-//! match reader.read(buf.as_slice()) {
-//! Some(nread) => println!("Read {} bytes", nread),
-//! None => println!("At the end of the stream!")
-//! }
-//! ```
-//!
-//! ```
-//! let tcp_stream = TcpStream::connect(addr);
-//! let writer = BufferedWriter::new(tcp_stream);
-//!
-//! writer.write("hello, world".as_bytes());
-//! writer.flush();
-//! ```
-//!
-//! ```
-//! let tcp_stream = TcpStream::connect(addr);
-//! let stream = BufferedStream::new(tcp_stream);
-//!
-//! stream.write("hello, world".as_bytes());
-//! stream.flush();
-//!
-//! let mut buf = vec::from_elem(100, 0u8);
-//! match stream.read(buf.as_slice()) {
-//! Some(nread) => println!("Read {} bytes", nread),
-//! None => println!("At the end of the stream!")
-//! }
-//! ```
-//!
-
-use prelude::*;
-
-use num;
-use vec;
-use super::{Stream, Decorator};
-
-// libuv recommends 64k buffers to maximize throughput
-// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
-static DEFAULT_CAPACITY: uint = 64 * 1024;
-
-/// Wraps a Reader and buffers input from it
-pub struct BufferedReader<R> {
- priv inner: R,
- priv buf: ~[u8],
- priv pos: uint,
- priv cap: uint
-}
-
-impl<R: Reader> BufferedReader<R> {
- /// Creates a new `BufferedReader` with with the specified buffer capacity
- pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
- // It's *much* faster to create an uninitialized buffer than it is to
- // fill everything in with 0. This buffer is entirely an implementation
- // detail and is never exposed, so we're safe to not initialize
- // everything up-front. This allows creation of BufferedReader instances
- // to be very cheap (large mallocs are not nearly as expensive as large
- // callocs).
- let mut buf = vec::with_capacity(cap);
- unsafe { vec::raw::set_len(&mut buf, cap); }
- BufferedReader {
- inner: inner,
- buf: buf,
- pos: 0,
- cap: 0
- }
- }
-
- /// Creates a new `BufferedReader` with a default buffer capacity
- pub fn new(inner: R) -> BufferedReader<R> {
- BufferedReader::with_capacity(DEFAULT_CAPACITY, inner)
- }
-}
-
-impl<R: Reader> Buffer for BufferedReader<R> {
- fn fill<'a>(&'a mut self) -> &'a [u8] {
- if self.pos == self.cap {
- match self.inner.read(self.buf) {
- Some(cap) => {
- self.pos = 0;
- self.cap = cap;
- }
- None => {}
- }
- }
- return self.buf.slice(self.pos, self.cap);
- }
-
- fn consume(&mut self, amt: uint) {
- self.pos += amt;
- assert!(self.pos <= self.cap);
- }
-}
-
-impl<R: Reader> Reader for BufferedReader<R> {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- let nread = {
- let available = self.fill();
- if available.len() == 0 {
- return None;
- }
- let nread = num::min(available.len(), buf.len());
- vec::bytes::copy_memory(buf, available, nread);
- nread
- };
- self.pos += nread;
- Some(nread)
- }
-
- fn eof(&mut self) -> bool {
- self.pos == self.cap && self.inner.eof()
- }
-}
-
-impl<R: Reader> Decorator<R> for BufferedReader<R> {
- fn inner(self) -> R { self.inner }
- fn inner_ref<'a>(&'a self) -> &'a R { &self.inner }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { &mut self.inner }
-}
-
-/// Wraps a Writer and buffers output to it
-///
-/// Note that `BufferedWriter` will NOT flush its buffer when dropped.
-pub struct BufferedWriter<W> {
- priv inner: W,
- priv buf: ~[u8],
- priv pos: uint
-}
-
-impl<W: Writer> BufferedWriter<W> {
- /// Creates a new `BufferedWriter` with with the specified buffer capacity
- pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
- // See comments in BufferedReader for why this uses unsafe code.
- let mut buf = vec::with_capacity(cap);
- unsafe { vec::raw::set_len(&mut buf, cap); }
- BufferedWriter {
- inner: inner,
- buf: buf,
- pos: 0
- }
- }
-
- /// Creates a new `BufferedWriter` with a default buffer capacity
- pub fn new(inner: W) -> BufferedWriter<W> {
- BufferedWriter::with_capacity(DEFAULT_CAPACITY, inner)
- }
-}
-
-impl<W: Writer> Writer for BufferedWriter<W> {
- fn write(&mut self, buf: &[u8]) {
- if self.pos + buf.len() > self.buf.len() {
- self.flush();
- }
-
- if buf.len() > self.buf.len() {
- self.inner.write(buf);
- } else {
- let dst = self.buf.mut_slice_from(self.pos);
- vec::bytes::copy_memory(dst, buf, buf.len());
- self.pos += buf.len();
- }
- }
-
- fn flush(&mut self) {
- if self.pos != 0 {
- self.inner.write(self.buf.slice_to(self.pos));
- self.pos = 0;
- }
- self.inner.flush();
- }
-}
-
-impl<W: Writer> Decorator<W> for BufferedWriter<W> {
- fn inner(self) -> W { self.inner }
- fn inner_ref<'a>(&'a self) -> &'a W { &self.inner }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { &mut self.inner }
-}
-
-/// Wraps a Writer and buffers output to it, flushing whenever a newline (0xa,
-/// '\n') is detected.
-///
-/// Note that this structure does NOT flush the output when dropped.
-pub struct LineBufferedWriter<W> {
- priv inner: BufferedWriter<W>,
-}
-
-impl<W: Writer> LineBufferedWriter<W> {
- /// Creates a new `LineBufferedWriter`
- pub fn new(inner: W) -> LineBufferedWriter<W> {
- // Lines typically aren't that long, don't use a giant buffer
- LineBufferedWriter {
- inner: BufferedWriter::with_capacity(1024, inner)
- }
- }
-}
-
-impl<W: Writer> Writer for LineBufferedWriter<W> {
- fn write(&mut self, buf: &[u8]) {
- match buf.iter().position(|&b| b == '\n' as u8) {
- Some(i) => {
- self.inner.write(buf.slice_to(i + 1));
- self.inner.flush();
- self.inner.write(buf.slice_from(i + 1));
- }
- None => self.inner.write(buf),
- }
- }
-
- fn flush(&mut self) { self.inner.flush() }
-}
-
-impl<W: Writer> Decorator<W> for LineBufferedWriter<W> {
- fn inner(self) -> W { self.inner.inner() }
- fn inner_ref<'a>(&'a self) -> &'a W { self.inner.inner_ref() }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { self.inner.inner_mut_ref() }
-}
-
-struct InternalBufferedWriter<W>(BufferedWriter<W>);
-
-impl<W: Reader> Reader for InternalBufferedWriter<W> {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.inner.read(buf) }
- fn eof(&mut self) -> bool { self.inner.eof() }
-}
-
-/// Wraps a Stream and buffers input and output to and from it
-///
-/// Note that `BufferedStream` will NOT flush its output buffer when dropped.
-pub struct BufferedStream<S> {
- priv inner: BufferedReader<InternalBufferedWriter<S>>
-}
-
-impl<S: Stream> BufferedStream<S> {
- pub fn with_capacities(reader_cap: uint, writer_cap: uint, inner: S)
- -> BufferedStream<S> {
- let writer = BufferedWriter::with_capacity(writer_cap, inner);
- let internal_writer = InternalBufferedWriter(writer);
- let reader = BufferedReader::with_capacity(reader_cap,
- internal_writer);
- BufferedStream { inner: reader }
- }
-
- pub fn new(inner: S) -> BufferedStream<S> {
- BufferedStream::with_capacities(DEFAULT_CAPACITY, DEFAULT_CAPACITY,
- inner)
- }
-}
-
-impl<S: Stream> Buffer for BufferedStream<S> {
- fn fill<'a>(&'a mut self) -> &'a [u8] { self.inner.fill() }
- fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
-}
-
-impl<S: Stream> Reader for BufferedStream<S> {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.inner.read(buf) }
- fn eof(&mut self) -> bool { self.inner.eof() }
-}
-
-impl<S: Stream> Writer for BufferedStream<S> {
- fn write(&mut self, buf: &[u8]) { self.inner.inner.write(buf) }
- fn flush(&mut self) { self.inner.inner.flush() }
-}
-
-impl<S: Stream> Decorator<S> for BufferedStream<S> {
- fn inner(self) -> S { self.inner.inner.inner() }
- fn inner_ref<'a>(&'a self) -> &'a S { self.inner.inner.inner_ref() }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut S {
- self.inner.inner.inner_mut_ref()
- }
-}
-
-#[cfg(test)]
-mod test {
- use prelude::*;
- use super::*;
- use io;
- use super::super::mem::{MemReader, MemWriter};
- use Harness = extra::test::BenchHarness;
-
- /// A type, free to create, primarily intended for benchmarking creation of wrappers that, just
- /// for construction, don't need a Reader/Writer that does anything useful. Is equivalent to
- /// `/dev/null` in semantics.
- #[deriving(Clone,Eq,Ord)]
- pub struct NullStream;
-
- impl Reader for NullStream {
- fn read(&mut self, _: &mut [u8]) -> Option<uint> {
- None
- }
-
- fn eof(&mut self) -> bool {
- true
- }
- }
-
- impl Writer for NullStream {
- fn write(&mut self, _: &[u8]) { }
- }
-
- #[test]
- fn test_buffered_reader() {
- let inner = MemReader::new(~[0, 1, 2, 3, 4]);
- let mut reader = BufferedReader::with_capacity(2, inner);
-
- let mut buf = [0, 0, 0];
- let nread = reader.read(buf);
- assert_eq!(Some(2), nread);
- assert_eq!([0, 1, 0], buf);
- assert!(!reader.eof());
-
- let mut buf = [0];
- let nread = reader.read(buf);
- assert_eq!(Some(1), nread);
- assert_eq!([2], buf);
- assert!(!reader.eof());
-
- let mut buf = [0, 0, 0];
- let nread = reader.read(buf);
- assert_eq!(Some(1), nread);
- assert_eq!([3, 0, 0], buf);
- assert!(!reader.eof());
-
- let nread = reader.read(buf);
- assert_eq!(Some(1), nread);
- assert_eq!([4, 0, 0], buf);
- assert!(reader.eof());
-
- assert_eq!(None, reader.read(buf));
- }
-
- #[test]
- fn test_buffered_writer() {
- let inner = MemWriter::new();
- let mut writer = BufferedWriter::with_capacity(2, inner);
-
- writer.write([0, 1]);
- assert_eq!([], writer.inner_ref().inner_ref().as_slice());
-
- writer.write([2]);
- assert_eq!([0, 1], writer.inner_ref().inner_ref().as_slice());
-
- writer.write([3]);
- assert_eq!([0, 1], writer.inner_ref().inner_ref().as_slice());
-
- writer.flush();
- assert_eq!([0, 1, 2, 3], writer.inner_ref().inner_ref().as_slice());
-
- writer.write([4]);
- writer.write([5]);
- assert_eq!([0, 1, 2, 3], writer.inner_ref().inner_ref().as_slice());
-
- writer.write([6]);
- assert_eq!([0, 1, 2, 3, 4, 5],
- writer.inner_ref().inner_ref().as_slice());
-
- writer.write([7, 8]);
- assert_eq!([0, 1, 2, 3, 4, 5, 6],
- writer.inner_ref().inner_ref().as_slice());
-
- writer.write([9, 10, 11]);
- assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
- writer.inner_ref().inner_ref().as_slice());
-
- writer.flush();
- assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
- writer.inner_ref().inner_ref().as_slice());
- }
-
- // This is just here to make sure that we don't infinite loop in the
- // newtype struct autoderef weirdness
- #[test]
- fn test_buffered_stream() {
- struct S;
-
- impl io::Writer for S {
- fn write(&mut self, _: &[u8]) {}
- }
-
- impl io::Reader for S {
- fn read(&mut self, _: &mut [u8]) -> Option<uint> { None }
- fn eof(&mut self) -> bool { true }
- }
-
- let mut stream = BufferedStream::new(S);
- let mut buf = [];
- stream.read(buf);
- stream.eof();
- stream.write(buf);
- stream.flush();
- }
-
- #[test]
- fn test_read_until() {
- let inner = MemReader::new(~[0, 1, 2, 1, 0]);
- let mut reader = BufferedReader::with_capacity(2, inner);
- assert_eq!(reader.read_until(0), Some(~[0]));
- assert_eq!(reader.read_until(2), Some(~[1, 2]));
- assert_eq!(reader.read_until(1), Some(~[1]));
- assert_eq!(reader.read_until(8), Some(~[0]));
- assert_eq!(reader.read_until(9), None);
- }
-
- #[test]
- fn test_line_buffer() {
- let mut writer = LineBufferedWriter::new(MemWriter::new());
- writer.write([0]);
- assert_eq!(*writer.inner_ref().inner_ref(), ~[]);
- writer.write([1]);
- assert_eq!(*writer.inner_ref().inner_ref(), ~[]);
- writer.flush();
- assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1]);
- writer.write([0, '\n' as u8, 1]);
- assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8]);
- writer.flush();
- assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8, 1]);
- }
-
- #[bench]
- fn bench_buffered_reader(bh: &mut Harness) {
- bh.iter(|| {
- BufferedReader::new(NullStream);
- });
- }
-
- #[bench]
- fn bench_buffered_writer(bh: &mut Harness) {
- bh.iter(|| {
- BufferedWriter::new(NullStream);
- });
- }
-
- #[bench]
- fn bench_buffered_stream(bh: &mut Harness) {
- bh.iter(|| {
- BufferedStream::new(NullStream);
- });
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use option::Option;
-use comm::{GenericPort, GenericChan};
-use super::{Reader, Writer};
-
-struct PortReader<P>;
-
-impl<P: GenericPort<~[u8]>> PortReader<P> {
- pub fn new(_port: P) -> PortReader<P> { fail!() }
-}
-
-impl<P: GenericPort<~[u8]>> Reader for PortReader<P> {
- fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
-
- fn eof(&mut self) -> bool { fail!() }
-}
-
-struct ChanWriter<C>;
-
-impl<C: GenericChan<~[u8]>> ChanWriter<C> {
- pub fn new(_chan: C) -> ChanWriter<C> { fail!() }
-}
-
-impl<C: GenericChan<~[u8]>> Writer for ChanWriter<C> {
- fn write(&mut self, _buf: &[u8]) { fail!() }
-}
-
-struct ReaderPort<R>;
-
-impl<R: Reader> ReaderPort<R> {
- pub fn new(_reader: R) -> ReaderPort<R> { fail!() }
-}
-
-impl<R: Reader> GenericPort<~[u8]> for ReaderPort<R> {
- fn recv(&self) -> ~[u8] { fail!() }
-
- fn try_recv(&self) -> Option<~[u8]> { fail!() }
-}
-
-struct WriterChan<W>;
-
-impl<W: Writer> WriterChan<W> {
- pub fn new(_writer: W) -> WriterChan<W> { fail!() }
-}
-
-impl<W: Writer> GenericChan<~[u8]> for WriterChan<W> {
- fn send(&self, _x: ~[u8]) { fail!() }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Utility mixins that apply to all Readers and Writers
-
-// XXX: Not sure how this should be structured
-// XXX: Iteration should probably be considered separately
-
-use iter::Iterator;
-use option::Option;
-use io::{Reader, Decorator};
-
-/// An iterator that reads a single byte on each iteration,
-/// until `.read_byte()` returns `None`.
-///
-/// # Notes about the Iteration Protocol
-///
-/// The `ByteIterator` may yield `None` and thus terminate
-/// an iteration, but continue to yield elements if iteration
-/// is attempted again.
-///
-/// # Failure
-///
-/// Raises the same conditions as the `read` method, for
-/// each call to its `.next()` method.
-/// Yields `None` if the condition is handled.
-pub struct ByteIterator<T> {
- priv reader: T,
-}
-
-impl<R: Reader> ByteIterator<R> {
- pub fn new(r: R) -> ByteIterator<R> {
- ByteIterator { reader: r }
- }
-}
-
-impl<R> Decorator<R> for ByteIterator<R> {
- fn inner(self) -> R { self.reader }
- fn inner_ref<'a>(&'a self) -> &'a R { &self.reader }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { &mut self.reader }
-}
-
-impl<'self, R: Reader> Iterator<u8> for ByteIterator<R> {
- #[inline]
- fn next(&mut self) -> Option<u8> {
- self.reader.read_byte()
- }
-}
-
-pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
- assert!(size <= 8u);
- match size {
- 1u => f(&[n as u8]),
- 2u => f(&[n as u8,
- (n >> 8) as u8]),
- 4u => f(&[n as u8,
- (n >> 8) as u8,
- (n >> 16) as u8,
- (n >> 24) as u8]),
- 8u => f(&[n as u8,
- (n >> 8) as u8,
- (n >> 16) as u8,
- (n >> 24) as u8,
- (n >> 32) as u8,
- (n >> 40) as u8,
- (n >> 48) as u8,
- (n >> 56) as u8]),
- _ => {
-
- let mut bytes: ~[u8] = ~[];
- let mut i = size;
- let mut n = n;
- while i > 0u {
- bytes.push((n & 255_u64) as u8);
- n >>= 8_u64;
- i -= 1u;
- }
- f(bytes)
- }
- }
-}
-
-pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
- assert!(size <= 8u);
- match size {
- 1u => f(&[n as u8]),
- 2u => f(&[(n >> 8) as u8,
- n as u8]),
- 4u => f(&[(n >> 24) as u8,
- (n >> 16) as u8,
- (n >> 8) as u8,
- n as u8]),
- 8u => f(&[(n >> 56) as u8,
- (n >> 48) as u8,
- (n >> 40) as u8,
- (n >> 32) as u8,
- (n >> 24) as u8,
- (n >> 16) as u8,
- (n >> 8) as u8,
- n as u8]),
- _ => {
- let mut bytes: ~[u8] = ~[];
- let mut i = size;
- while i > 0u {
- let shift = ((i - 1u) * 8u) as u64;
- bytes.push((n >> shift) as u8);
- i -= 1u;
- }
- f(bytes)
- }
- }
-}
-
-pub fn u64_from_be_bytes(data: &[u8],
- start: uint,
- size: uint)
- -> u64 {
- let mut sz = size;
- assert!((sz <= 8u));
- let mut val = 0_u64;
- let mut pos = start;
- while sz > 0u {
- sz -= 1u;
- val += (data[pos] as u64) << ((sz * 8u) as u64);
- pos += 1u;
- }
- return val;
-}
-
-#[cfg(test)]
-mod test {
- use option::{None, Option, Some};
- use io::mem::{MemReader, MemWriter};
- use io::{Reader, io_error, placeholder_error};
- use vec::ImmutableVector;
-
- struct InitialZeroByteReader {
- count: int,
- }
-
- impl Reader for InitialZeroByteReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- if self.count == 0 {
- self.count = 1;
- Some(0)
- } else {
- buf[0] = 10;
- Some(1)
- }
- }
- fn eof(&mut self) -> bool {
- false
- }
- }
-
- struct EofReader;
-
- impl Reader for EofReader {
- fn read(&mut self, _: &mut [u8]) -> Option<uint> {
- None
- }
- fn eof(&mut self) -> bool {
- false
- }
- }
-
- struct ErroringReader;
-
- impl Reader for ErroringReader {
- fn read(&mut self, _: &mut [u8]) -> Option<uint> {
- io_error::cond.raise(placeholder_error());
- None
- }
- fn eof(&mut self) -> bool {
- false
- }
- }
-
- struct PartialReader {
- count: int,
- }
-
- impl Reader for PartialReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- if self.count == 0 {
- self.count = 1;
- buf[0] = 10;
- buf[1] = 11;
- Some(2)
- } else {
- buf[0] = 12;
- buf[1] = 13;
- Some(2)
- }
- }
- fn eof(&mut self) -> bool {
- false
- }
- }
-
- struct ErroringLaterReader {
- count: int,
- }
-
- impl Reader for ErroringLaterReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- if self.count == 0 {
- self.count = 1;
- buf[0] = 10;
- Some(1)
- } else {
- io_error::cond.raise(placeholder_error());
- None
- }
- }
- fn eof(&mut self) -> bool {
- false
- }
- }
-
- struct ThreeChunkReader {
- count: int,
- }
-
- impl Reader for ThreeChunkReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- if self.count == 0 {
- self.count = 1;
- buf[0] = 10;
- buf[1] = 11;
- Some(2)
- } else if self.count == 1 {
- self.count = 2;
- buf[0] = 12;
- buf[1] = 13;
- Some(2)
- } else {
- None
- }
- }
- fn eof(&mut self) -> bool {
- false
- }
- }
-
- #[test]
- fn read_byte() {
- let mut reader = MemReader::new(~[10]);
- let byte = reader.read_byte();
- assert!(byte == Some(10));
- }
-
- #[test]
- fn read_byte_0_bytes() {
- let mut reader = InitialZeroByteReader {
- count: 0,
- };
- let byte = reader.read_byte();
- assert!(byte == Some(10));
- }
-
- #[test]
- fn read_byte_eof() {
- let mut reader = EofReader;
- let byte = reader.read_byte();
- assert!(byte == None);
- }
-
- #[test]
- fn read_byte_error() {
- let mut reader = ErroringReader;
- io_error::cond.trap(|_| {
- }).inside(|| {
- let byte = reader.read_byte();
- assert!(byte == None);
- });
- }
-
- #[test]
- fn bytes_0_bytes() {
- let reader = InitialZeroByteReader {
- count: 0,
- };
- let byte = reader.bytes().next();
- assert!(byte == Some(10));
- }
-
- #[test]
- fn bytes_eof() {
- let reader = EofReader;
- let byte = reader.bytes().next();
- assert!(byte == None);
- }
-
- #[test]
- fn bytes_error() {
- let reader = ErroringReader;
- let mut it = reader.bytes();
- io_error::cond.trap(|_| ()).inside(|| {
- let byte = it.next();
- assert!(byte == None);
- })
- }
-
- #[test]
- fn read_bytes() {
- let mut reader = MemReader::new(~[10, 11, 12, 13]);
- let bytes = reader.read_bytes(4);
- assert!(bytes == ~[10, 11, 12, 13]);
- }
-
- #[test]
- fn read_bytes_partial() {
- let mut reader = PartialReader {
- count: 0,
- };
- let bytes = reader.read_bytes(4);
- assert!(bytes == ~[10, 11, 12, 13]);
- }
-
- #[test]
- fn read_bytes_eof() {
- let mut reader = MemReader::new(~[10, 11]);
- io_error::cond.trap(|_| {
- }).inside(|| {
- assert!(reader.read_bytes(4) == ~[10, 11]);
- })
- }
-
- #[test]
- fn push_bytes() {
- let mut reader = MemReader::new(~[10, 11, 12, 13]);
- let mut buf = ~[8, 9];
- reader.push_bytes(&mut buf, 4);
- assert!(buf == ~[8, 9, 10, 11, 12, 13]);
- }
-
- #[test]
- fn push_bytes_partial() {
- let mut reader = PartialReader {
- count: 0,
- };
- let mut buf = ~[8, 9];
- reader.push_bytes(&mut buf, 4);
- assert!(buf == ~[8, 9, 10, 11, 12, 13]);
- }
-
- #[test]
- fn push_bytes_eof() {
- let mut reader = MemReader::new(~[10, 11]);
- let mut buf = ~[8, 9];
- io_error::cond.trap(|_| {
- }).inside(|| {
- reader.push_bytes(&mut buf, 4);
- assert!(buf == ~[8, 9, 10, 11]);
- })
- }
-
- #[test]
- fn push_bytes_error() {
- let mut reader = ErroringLaterReader {
- count: 0,
- };
- let mut buf = ~[8, 9];
- io_error::cond.trap(|_| { } ).inside(|| {
- reader.push_bytes(&mut buf, 4);
- });
- assert!(buf == ~[8, 9, 10]);
- }
-
- #[test]
- #[should_fail]
- fn push_bytes_fail_reset_len() {
- // push_bytes unsafely sets the vector length. This is testing that
- // upon failure the length is reset correctly.
- let mut reader = ErroringLaterReader {
- count: 0,
- };
- let buf = @mut ~[8, 9];
- (|| {
- reader.push_bytes(&mut *buf, 4);
- }).finally(|| {
- // NB: Using rtassert here to trigger abort on failure since this is a should_fail test
- // FIXME: #7049 This fails because buf is still borrowed
- //rtassert!(*buf == ~[8, 9, 10]);
- })
- }
-
- #[test]
- fn read_to_end() {
- let mut reader = ThreeChunkReader {
- count: 0,
- };
- let buf = reader.read_to_end();
- assert!(buf == ~[10, 11, 12, 13]);
- }
-
- #[test]
- #[should_fail]
- fn read_to_end_error() {
- let mut reader = ThreeChunkReader {
- count: 0,
- };
- let buf = reader.read_to_end();
- assert!(buf == ~[10, 11]);
- }
-
- #[test]
- fn test_read_write_le_mem() {
- let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
-
- let mut writer = MemWriter::new();
- for i in uints.iter() {
- writer.write_le_u64(*i);
- }
-
- let mut reader = MemReader::new(writer.inner());
- for i in uints.iter() {
- assert!(reader.read_le_u64() == *i);
- }
- }
-
-
- #[test]
- fn test_read_write_be() {
- let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
-
- let mut writer = MemWriter::new();
- for i in uints.iter() {
- writer.write_be_u64(*i);
- }
-
- let mut reader = MemReader::new(writer.inner());
- for i in uints.iter() {
- assert!(reader.read_be_u64() == *i);
- }
- }
-
- #[test]
- fn test_read_be_int_n() {
- let ints = [::i32::min_value, -123456, -42, -5, 0, 1, ::i32::max_value];
-
- let mut writer = MemWriter::new();
- for i in ints.iter() {
- writer.write_be_i32(*i);
- }
-
- let mut reader = MemReader::new(writer.inner());
- for i in ints.iter() {
- // this tests that the sign extension is working
- // (comparing the values as i32 would not test this)
- assert!(reader.read_be_int_n(4) == *i as i64);
- }
- }
-
- #[test]
- fn test_read_f32() {
- //big-endian floating-point 8.1250
- let buf = ~[0x41, 0x02, 0x00, 0x00];
-
- let mut writer = MemWriter::new();
- writer.write(buf);
-
- let mut reader = MemReader::new(writer.inner());
- let f = reader.read_be_f32();
- assert!(f == 8.1250);
- }
-
- #[test]
- fn test_read_write_f32() {
- let f:f32 = 8.1250;
-
- let mut writer = MemWriter::new();
- writer.write_be_f32(f);
- writer.write_le_f32(f);
-
- let mut reader = MemReader::new(writer.inner());
- assert!(reader.read_be_f32() == 8.1250);
- assert!(reader.read_le_f32() == 8.1250);
- }
-
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Some various other I/O types
-
-// FIXME(#3660): should move to libextra
-
-use prelude::*;
-use super::*;
-
-/// A Writer decorator that compresses using the 'deflate' scheme
-pub struct DeflateWriter<W> {
- priv inner_writer: W
-}
-
-impl<W: Writer> DeflateWriter<W> {
- pub fn new(inner_writer: W) -> DeflateWriter<W> {
- DeflateWriter {
- inner_writer: inner_writer
- }
- }
-}
-
-impl<W: Writer> Writer for DeflateWriter<W> {
- fn write(&mut self, _buf: &[u8]) { fail!() }
-
- fn flush(&mut self) { fail!() }
-}
-
-impl<W: Writer> Decorator<W> for DeflateWriter<W> {
- fn inner(self) -> W {
- match self {
- DeflateWriter { inner_writer: w } => w
- }
- }
-
- fn inner_ref<'a>(&'a self) -> &'a W {
- match *self {
- DeflateWriter { inner_writer: ref w } => w
- }
- }
-
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W {
- match *self {
- DeflateWriter { inner_writer: ref mut w } => w
- }
- }
-}
-
-/// A Reader decorator that decompresses using the 'deflate' scheme
-pub struct InflateReader<R> {
- priv inner_reader: R
-}
-
-impl<R: Reader> InflateReader<R> {
- pub fn new(inner_reader: R) -> InflateReader<R> {
- InflateReader {
- inner_reader: inner_reader
- }
- }
-}
-
-impl<R: Reader> Reader for InflateReader<R> {
- fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
-
- fn eof(&mut self) -> bool { fail!() }
-}
-
-impl<R: Reader> Decorator<R> for InflateReader<R> {
- fn inner(self) -> R {
- match self {
- InflateReader { inner_reader: r } => r
- }
- }
-
- fn inner_ref<'a>(&'a self) -> &'a R {
- match *self {
- InflateReader { inner_reader: ref r } => r
- }
- }
-
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R {
- match *self {
- InflateReader { inner_reader: ref mut r } => r
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use prelude::*;
- use super::*;
- use super::super::mem::*;
- use super::super::Decorator;
-
- use str;
-
- #[test]
- #[ignore]
- fn smoke_test() {
- let mem_writer = MemWriter::new();
- let mut deflate_writer = DeflateWriter::new(mem_writer);
- let in_msg = "test";
- let in_bytes = in_msg.as_bytes();
- deflate_writer.write(in_bytes);
- deflate_writer.flush();
- let buf = deflate_writer.inner().inner();
- let mem_reader = MemReader::new(buf);
- let mut inflate_reader = InflateReader::new(mem_reader);
- let mut out_bytes = [0, .. 100];
- let bytes_read = inflate_reader.read(out_bytes).unwrap();
- assert_eq!(bytes_read, in_bytes.len());
- let out_msg = str::from_utf8(out_bytes);
- assert!(in_msg == out_msg);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! Synchronous File I/O
-
-This module provides a set of functions and traits for working
-with regular files & directories on a filesystem.
-
-At the top-level of the module are a set of freestanding functions, associated
-with various filesystem operations. They all operate on a `Path` object.
-
-All operations in this module, including those as part of `File` et al
-block the task during execution. Most will raise `std::io::io_error`
-conditions in the event of failure.
-
-Also included in this module is an implementation block on the `Path` object
-defined in `std::path::Path`. The impl adds useful methods about inspecting the
-metadata of a file. This includes getting the `stat` information, reading off
-particular bits of it, etc.
-
-# Example
-
- use std::io::{File, fs};
-
- let path = Path::new("foo.txt");
-
- // create the file, whether it exists or not
- let mut file = File::create(&path);
- file.write(bytes!("foobar"));
-
- // open the file in read-only mode
- let mut file = File::open(&path);
- file.read_to_end();
-
- println!("{}", path.stat().size);
- fs::symlink(&path, &Path::new("bar.txt"));
- fs::unlink(&path);
-
-*/
-
-use c_str::ToCStr;
-use clone::Clone;
-use iter::Iterator;
-use super::{Reader, Writer, Seek};
-use super::{SeekStyle, Read, Write, Open, IoError, Truncate,
- FileMode, FileAccess, FileStat, io_error, FilePermission};
-use rt::rtio::{RtioFileStream, IoFactory, with_local_io};
-use io;
-use option::{Some, None, Option};
-use result::{Ok, Err, Result};
-use path;
-use path::{Path, GenericPath};
-use vec::{OwnedVector, ImmutableVector};
-
-/// Unconstrained file access type that exposes read and write operations
-///
-/// Can be constructed via `File::open()`, `File::create()`, and
-/// `File::open_mode()`.
-///
-/// # Errors
-///
-/// This type will raise an io_error condition if operations are attempted against
-/// it for which its underlying file descriptor was not configured at creation
-/// time, via the `FileAccess` parameter to `File::open_mode()`.
-pub struct File {
- priv fd: ~RtioFileStream,
- priv path: Path,
- priv last_nread: int,
-}
-
-fn io_raise<T>(f: |io: &mut IoFactory| -> Result<T, IoError>) -> Option<T> {
- with_local_io(|io| {
- match f(io) {
- Ok(t) => Some(t),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
-}
-
-impl File {
- /// Open a file at `path` in the mode specified by the `mode` and `access`
- /// arguments
- ///
- /// # Example
- ///
- /// use std::io::{File, io_error, Open, ReadWrite};
- ///
- /// let p = Path::new("/some/file/path.txt");
- ///
- /// io_error::cond.trap(|_| {
- /// // hoo-boy...
- /// }).inside(|| {
- /// let file = match File::open_mode(&p, Open, ReadWrite) {
- /// Some(s) => s,
- /// None => fail!("whoops! I'm sure this raised, anyways..")
- /// };
- /// // do some stuff with that file
- ///
- /// // the file will be closed at the end of this block
- /// })
- /// // ..
- ///
- /// `FileMode` and `FileAccess` provide information about the permissions
- /// context in which a given stream is created. More information about them
- /// can be found in `std::io`'s docs. If a file is opened with `Write`
- /// or `ReadWrite` access, then it will be created it it does not already
- /// exist.
- ///
- /// Note that, with this function, a `File` is returned regardless of the
- /// access-limitations indicated by `FileAccess` (e.g. calling `write` on a
- /// `File` opened as `Read` will raise an `io_error` condition at runtime).
- ///
- /// # Errors
- ///
- /// This function will raise an `io_error` condition under a number of
- /// different circumstances, to include but not limited to:
- ///
- /// * Opening a file that does not exist with `Read` access.
- /// * Attempting to open a file with a `FileAccess` that the user lacks
- /// permissions for
- /// * Filesystem-level errors (full disk, etc)
- pub fn open_mode(path: &Path,
- mode: FileMode,
- access: FileAccess) -> Option<File> {
- with_local_io(|io| {
- match io.fs_open(&path.to_c_str(), mode, access) {
- Ok(fd) => Some(File {
- path: path.clone(),
- fd: fd,
- last_nread: -1
- }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-
- /// Attempts to open a file in read-only mode. This function is equivalent to
- /// `File::open_mode(path, Open, Read)`, and will raise all of the same
- /// errors that `File::open_mode` does.
- ///
- /// For more information, see the `File::open_mode` function.
- ///
- /// # Example
- ///
- /// use std::io::File;
- ///
- /// let contents = File::open(&Path::new("foo.txt")).read_to_end();
- pub fn open(path: &Path) -> Option<File> {
- File::open_mode(path, Open, Read)
- }
-
- /// Attempts to create a file in write-only mode. This function is
- /// equivalent to `File::open_mode(path, Truncate, Write)`, and will
- /// raise all of the same errors that `File::open_mode` does.
- ///
- /// For more information, see the `File::open_mode` function.
- ///
- /// # Example
- ///
- /// use std::io::File;
- ///
- /// let mut f = File::create(&Path::new("foo.txt"));
- /// f.write(bytes!("This is a sample file"));
- pub fn create(path: &Path) -> Option<File> {
- File::open_mode(path, Truncate, Write)
- }
-
- /// Returns the original path which was used to open this file.
- pub fn path<'a>(&'a self) -> &'a Path {
- &self.path
- }
-
- /// Synchronizes all modifications to this file to its permanent storage
- /// device. This will flush any internal buffers necessary to perform this
- /// operation.
- ///
- /// # Errors
- ///
- /// This function will raise on the `io_error` condition on failure.
- pub fn fsync(&mut self) {
- self.fd.fsync().map_err(|e| io_error::cond.raise(e));
- }
-
- /// This function is similar to `fsync`, except that it may not synchronize
- /// file metadata to the filesystem. This is intended for use case which
- /// must synchronize content, but don't need the metadata on disk. The goal
- /// of this method is to reduce disk operations.
- ///
- /// # Errors
- ///
- /// This function will raise on the `io_error` condition on failure.
- pub fn datasync(&mut self) {
- self.fd.datasync().map_err(|e| io_error::cond.raise(e));
- }
-
- /// Either truncates or extends the underlying file, updating the size of
- /// this file to become `size`. This is equivalent to unix's `truncate`
- /// function.
- ///
- /// If the `size` is less than the current file's size, then the file will
- /// be shrunk. If it is greater than the current file's size, then the file
- /// will be extended to `size` and have all of the intermediate data filled
- /// in with 0s.
- ///
- /// # Errors
- ///
- /// On error, this function will raise on the `io_error` condition.
- pub fn truncate(&mut self, size: i64) {
- self.fd.truncate(size).map_err(|e| io_error::cond.raise(e));
- }
-}
-
-/// Unlink a file from the underlying filesystem.
-///
-/// # Example
-///
-/// use std::io::fs;
-///
-/// let p = Path::new("/some/file/path.txt");
-/// fs::unlink(&p);
-/// // if we made it here without failing, then the
-/// // unlink operation was successful
-///
-/// Note that, just because an unlink call was successful, it is not
-/// guaranteed that a file is immediately deleted (e.g. depending on
-/// platform, other open file descriptors may prevent immediate removal)
-///
-/// # Errors
-///
-/// This function will raise an `io_error` condition if the path points to a
-/// directory, the user lacks permissions to remove the file, or if some
-/// other filesystem-level error occurs.
-pub fn unlink(path: &Path) {
- io_raise(|io| io.fs_unlink(&path.to_c_str()));
-}
-
-/// Given a path, query the file system to get information about a file,
-/// directory, etc. This function will traverse symlinks to query
-/// information about the destination file.
-///
-/// Returns a fully-filled out stat structure on succes, and on failure it
-/// will return a dummy stat structure (it is expected that the condition
-/// raised is handled as well).
-///
-/// # Example
-///
-/// use std::io;
-/// use std::io::fs;
-///
-/// let p = Path::new("/some/file/path.txt");
-/// match io::result(|| fs::stat(&p)) {
-/// Ok(stat) => { /* ... */ }
-/// Err(e) => { /* handle error */ }
-/// }
-///
-/// # Errors
-///
-/// This call will raise an `io_error` condition if the user lacks the
-/// requisite permissions to perform a `stat` call on the given path or if
-/// there is no entry in the filesystem at the provided path.
-pub fn stat(path: &Path) -> FileStat {
- io_raise(|io| io.fs_stat(&path.to_c_str())).unwrap_or_else(dummystat)
-}
-
-fn dummystat() -> FileStat {
- FileStat {
- path: Path::new(""),
- size: 0,
- kind: io::TypeFile,
- perm: 0,
- created: 0,
- modified: 0,
- accessed: 0,
- unstable: io::UnstableFileStat {
- device: 0,
- inode: 0,
- rdev: 0,
- nlink: 0,
- uid: 0,
- gid: 0,
- blksize: 0,
- blocks: 0,
- flags: 0,
- gen: 0,
- }
- }
-}
-
-/// Perform the same operation as the `stat` function, except that this
-/// function does not traverse through symlinks. This will return
-/// information about the symlink file instead of the file that it points
-/// to.
-///
-/// # Errors
-///
-/// See `stat`
-pub fn lstat(path: &Path) -> FileStat {
- io_raise(|io| io.fs_lstat(&path.to_c_str())).unwrap_or_else(dummystat)
-}
-
-/// Rename a file or directory to a new name.
-///
-/// # Example
-///
-/// use std::io::fs;
-///
-/// fs::rename(&Path::new("foo"), &Path::new("bar"));
-/// // Oh boy, nothing was raised!
-///
-/// # Errors
-///
-/// Will raise an `io_error` condition if the provided `path` doesn't exist,
-/// the process lacks permissions to view the contents, or if some other
-/// intermittent I/O error occurs.
-pub fn rename(from: &Path, to: &Path) {
- io_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str()));
-}
-
-/// Copies the contents of one file to another. This function will also
-/// copy the permission bits of the original file to the destination file.
-///
-/// Note that if `from` and `to` both point to the same file, then the file
-/// will likely get truncated by this operation.
-///
-/// # Example
-///
-/// use std::io::fs;
-///
-/// fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt"));
-/// // Oh boy, nothing was raised!
-///
-/// # Errors
-///
-/// Will raise an `io_error` condition is the following situtations, but is
-/// not limited to just these cases:
-///
-/// * The `from` path is not a file
-/// * The `from` file does not exist
-/// * The current process does not have the permission rights to access
-/// `from` or write `to`
-///
-/// Note that this copy is not atomic in that once the destination is
-/// ensured to not exist, there is nothing preventing the destination from
-/// being created and then destroyed by this operation.
-pub fn copy(from: &Path, to: &Path) {
- if !from.is_file() {
- return io_error::cond.raise(IoError {
- kind: io::MismatchedFileTypeForOperation,
- desc: "the source path is not an existing file",
- detail: None,
- });
- }
-
- let mut reader = match File::open(from) { Some(f) => f, None => return };
- let mut writer = match File::create(to) { Some(f) => f, None => return };
- let mut buf = [0, ..io::DEFAULT_BUF_SIZE];
-
- loop {
- match reader.read(buf) {
- Some(amt) => writer.write(buf.slice_to(amt)),
- None => break
- }
- }
-
- chmod(to, from.stat().perm)
-}
-
-/// Changes the permission mode bits found on a file or a directory. This
-/// function takes a mask from the `io` module
-///
-/// # Example
-///
-/// use std::io;
-/// use std::io::fs;
-///
-/// fs::chmod(&Path::new("file.txt"), io::UserFile);
-/// fs::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite);
-/// fs::chmod(&Path::new("dir"), io::UserDir);
-/// fs::chmod(&Path::new("file.exe"), io::UserExec);
-///
-/// # Errors
-///
-/// If this funciton encounters an I/O error, it will raise on the `io_error`
-/// condition. Some possible error situations are not having the permission to
-/// change the attributes of a file or the file not existing.
-pub fn chmod(path: &Path, mode: io::FilePermission) {
- io_raise(|io| io.fs_chmod(&path.to_c_str(), mode));
-}
-
-/// Change the user and group owners of a file at the specified path.
-///
-/// # Errors
-///
-/// This funtion will raise on the `io_error` condition on failure.
-pub fn chown(path: &Path, uid: int, gid: int) {
- io_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid));
-}
-
-/// Creates a new hard link on the filesystem. The `dst` path will be a
-/// link pointing to the `src` path. Note that systems often require these
-/// two paths to both be located on the same filesystem.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn link(src: &Path, dst: &Path) {
- io_raise(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str()));
-}
-
-/// Creates a new symbolic link on the filesystem. The `dst` path will be a
-/// symlink pointing to the `src` path.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn symlink(src: &Path, dst: &Path) {
- io_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str()));
-}
-
-/// Reads a symlink, returning the file that the symlink points to.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure. Failure
-/// conditions include reading a file that does not exist or reading a file
-/// which is not a symlink.
-pub fn readlink(path: &Path) -> Option<Path> {
- io_raise(|io| io.fs_readlink(&path.to_c_str()))
-}
-
-/// Create a new, empty directory at the provided path
-///
-/// # Example
-///
-/// use std::libc::S_IRWXU;
-/// use std::io::fs;
-///
-/// let p = Path::new("/some/dir");
-/// fs::mkdir(&p, S_IRWXU as int);
-/// // If we got here, our directory exists! Horray!
-///
-/// # Errors
-///
-/// This call will raise an `io_error` condition if the user lacks permissions
-/// to make a new directory at the provided path, or if the directory already
-/// exists.
-pub fn mkdir(path: &Path, mode: FilePermission) {
- io_raise(|io| io.fs_mkdir(&path.to_c_str(), mode));
-}
-
-/// Remove an existing, empty directory
-///
-/// # Example
-///
-/// use std::io::fs;
-///
-/// let p = Path::new("/some/dir");
-/// fs::rmdir(&p);
-/// // good riddance, you mean ol' directory
-///
-/// # Errors
-///
-/// This call will raise an `io_error` condition if the user lacks permissions
-/// to remove the directory at the provided path, or if the directory isn't
-/// empty.
-pub fn rmdir(path: &Path) {
- io_raise(|io| io.fs_rmdir(&path.to_c_str()));
-}
-
-/// Retrieve a vector containing all entries within a provided directory
-///
-/// # Example
-///
-/// use std::io::fs;
-///
-/// // one possible implementation of fs::walk_dir only visiting files
-/// fn visit_dirs(dir: &Path, cb: |&Path|) {
-/// if dir.is_dir() {
-/// let contents = fs::readdir(dir).unwrap();
-/// for entry in contents.iter() {
-/// if entry.is_dir() { visit_dirs(entry, cb); }
-/// else { cb(entry); }
-/// }
-/// }
-/// else { fail!("nope"); }
-/// }
-///
-/// # Errors
-///
-/// Will raise an `io_error` condition if the provided `from` doesn't exist,
-/// the process lacks permissions to view the contents or if the `path` points
-/// at a non-directory file
-pub fn readdir(path: &Path) -> ~[Path] {
- io_raise(|io| io.fs_readdir(&path.to_c_str(), 0)).unwrap_or_else(|| ~[])
-}
-
-/// Returns an iterator which will recursively walk the directory structure
-/// rooted at `path`. The path given will not be iterated over, and this will
-/// perform iteration in a top-down order.
-pub fn walk_dir(path: &Path) -> WalkIterator {
- WalkIterator { stack: readdir(path) }
-}
-
-/// An iterator which walks over a directory
-pub struct WalkIterator {
- priv stack: ~[Path],
-}
-
-impl Iterator<Path> for WalkIterator {
- fn next(&mut self) -> Option<Path> {
- match self.stack.shift_opt() {
- Some(path) => {
- if path.is_dir() {
- self.stack.push_all_move(readdir(&path));
- }
- Some(path)
- }
- None => None
- }
- }
-}
-
-/// Recursively create a directory and all of its parent components if they
-/// are missing.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition if an error
-/// happens, see `fs::mkdir` for more information about error conditions
-/// and performance.
-pub fn mkdir_recursive(path: &Path, mode: FilePermission) {
- // tjc: if directory exists but with different permissions,
- // should we return false?
- if path.is_dir() {
- return
- }
- if path.filename().is_some() {
- mkdir_recursive(&path.dir_path(), mode);
- }
- mkdir(path, mode)
-}
-
-/// Removes a directory at this path, after removing all its contents. Use
-/// carefully!
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition if an error
-/// happens. See `file::unlink` and `fs::readdir` for possible error
-/// conditions.
-pub fn rmdir_recursive(path: &Path) {
- let children = readdir(path);
- for child in children.iter() {
- if child.is_dir() {
- rmdir_recursive(child);
- } else {
- unlink(child);
- }
- }
- // Directory should now be empty
- rmdir(path);
-}
-
-/// Changes the timestamps for a file's last modification and access time.
-/// The file at the path specified will have its last access time set to
-/// `atime` and its modification time set to `mtime`. The times specified should
-/// be in milliseconds.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition if an error
-/// happens.
-// FIXME(#10301) these arguments should not be u64
-pub fn change_file_times(path: &Path, atime: u64, mtime: u64) {
- io_raise(|io| io.fs_utime(&path.to_c_str(), atime, mtime));
-}
-
-impl Reader for File {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- match self.fd.read(buf) {
- Ok(read) => {
- self.last_nread = read;
- match read {
- 0 => None,
- _ => Some(read as uint)
- }
- },
- Err(ioerr) => {
- // EOF is indicated by returning None
- if ioerr.kind != io::EndOfFile {
- io_error::cond.raise(ioerr);
- }
- return None;
- }
- }
- }
-
- fn eof(&mut self) -> bool { self.last_nread == 0 }
-}
-
-impl Writer for File {
- fn write(&mut self, buf: &[u8]) {
- match self.fd.write(buf) {
- Ok(()) => (),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- }
- }
- }
-}
-
-impl Seek for File {
- fn tell(&self) -> u64 {
- let res = self.fd.tell();
- match res {
- Ok(cursor) => cursor,
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- return -1;
- }
- }
- }
-
- fn seek(&mut self, pos: i64, style: SeekStyle) {
- match self.fd.seek(pos, style) {
- Ok(_) => {
- // successful seek resets EOF indicator
- self.last_nread = -1;
- ()
- },
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- }
- }
- }
-}
-
-impl path::Path {
- /// Get information on the file, directory, etc at this path.
- ///
- /// Consult the `file::stat` documentation for more info.
- ///
- /// This call preserves identical runtime/error semantics with `file::stat`.
- pub fn stat(&self) -> FileStat { stat(self) }
-
- /// Boolean value indicator whether the underlying file exists on the local
- /// filesystem. This will return true if the path points to either a
- /// directory or a file.
- ///
- /// # Errors
- ///
- /// Will not raise a condition
- pub fn exists(&self) -> bool {
- io::result(|| self.stat()).is_ok()
- }
-
- /// Whether the underlying implemention (be it a file path, or something
- /// else) points at a "regular file" on the FS. Will return false for paths
- /// to non-existent locations or directories or other non-regular files
- /// (named pipes, etc).
- ///
- /// # Errors
- ///
- /// Will not raise a condition
- pub fn is_file(&self) -> bool {
- match io::result(|| self.stat()) {
- Ok(s) => s.kind == io::TypeFile,
- Err(..) => false
- }
- }
-
- /// Whether the underlying implemention (be it a file path,
- /// or something else) is pointing at a directory in the underlying FS.
- /// Will return false for paths to non-existent locations or if the item is
- /// not a directory (eg files, named pipes, links, etc)
- ///
- /// # Errors
- ///
- /// Will not raise a condition
- pub fn is_dir(&self) -> bool {
- match io::result(|| self.stat()) {
- Ok(s) => s.kind == io::TypeDirectory,
- Err(..) => false
- }
- }
-}
-
-#[cfg(test)]
-#[allow(unused_imports)]
-mod test {
- use prelude::*;
- use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open,
- ReadWrite};
- use io;
- use str;
- use io::fs::{File, rmdir, mkdir, readdir, rmdir_recursive,
- mkdir_recursive, copy, unlink, stat, symlink, link,
- readlink, chmod, lstat, change_file_times};
- use util;
- use path::Path;
- use io;
- use ops::Drop;
-
- struct TempDir(Path);
-
- impl Drop for TempDir {
- fn drop(&mut self) {
- // Gee, seeing how we're testing the fs module I sure hope that we
- // at least implement this correctly!
- io::fs::rmdir_recursive(&**self);
- }
- }
-
- fn tmpdir() -> TempDir {
- use os;
- use rand;
- let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
- io::fs::mkdir(&ret, io::UserRWX);
- TempDir(ret)
- }
-
- macro_rules! test (
- { fn $name:ident() $b:block } => (
- mod $name {
- use prelude::*;
- use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open,
- ReadWrite};
- use io;
- use str;
- use io::fs::{File, rmdir, mkdir, readdir, rmdir_recursive,
- mkdir_recursive, copy, unlink, stat, symlink, link,
- readlink, chmod, lstat, change_file_times};
- use io::fs::test::tmpdir;
- use util;
-
- fn f() $b
-
- #[test] fn uv() { f() }
- #[test] fn native() {
- use rt::test::run_in_newsched_task;
- run_in_newsched_task(f);
- }
- }
- )
- )
-
- test!(fn file_test_io_smoke_test() {
- let message = "it's alright. have a good time";
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test.txt");
- {
- let mut write_stream = File::open_mode(filename, Open, ReadWrite);
- write_stream.write(message.as_bytes());
- }
- {
- let mut read_stream = File::open_mode(filename, Open, Read);
- let mut read_buf = [0, .. 1028];
- let read_str = match read_stream.read(read_buf).unwrap() {
- -1|0 => fail!("shouldn't happen"),
- n => str::from_utf8(read_buf.slice_to(n))
- };
- assert!(read_str == message.to_owned());
- }
- unlink(filename);
- })
-
- test!(fn invalid_path_raises() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_that_does_not_exist.txt");
- let mut called = false;
- io_error::cond.trap(|_| {
- called = true;
- }).inside(|| {
- let result = File::open_mode(filename, Open, Read);
- assert!(result.is_none());
- });
- assert!(called);
- })
-
- test!(fn file_test_iounlinking_invalid_path_should_raise_condition() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
- let mut called = false;
- io_error::cond.trap(|_| {
- called = true;
- }).inside(|| unlink(filename));
- assert!(called);
- })
-
- test!(fn file_test_io_non_positional_read() {
- let message = "ten-four";
- let mut read_mem = [0, .. 8];
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
- {
- let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(message.as_bytes());
- }
- {
- let mut read_stream = File::open_mode(filename, Open, Read);
- {
- let read_buf = read_mem.mut_slice(0, 4);
- read_stream.read(read_buf);
- }
- {
- let read_buf = read_mem.mut_slice(4, 8);
- read_stream.read(read_buf);
- }
- }
- unlink(filename);
- let read_str = str::from_utf8(read_mem);
- assert!(read_str == message.to_owned());
- })
-
- test!(fn file_test_io_seek_and_tell_smoke_test() {
- let message = "ten-four";
- let mut read_mem = [0, .. 4];
- let set_cursor = 4 as u64;
- let mut tell_pos_pre_read;
- let mut tell_pos_post_read;
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
- {
- let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(message.as_bytes());
- }
- {
- let mut read_stream = File::open_mode(filename, Open, Read);
- read_stream.seek(set_cursor as i64, SeekSet);
- tell_pos_pre_read = read_stream.tell();
- read_stream.read(read_mem);
- tell_pos_post_read = read_stream.tell();
- }
- unlink(filename);
- let read_str = str::from_utf8(read_mem);
- assert!(read_str == message.slice(4, 8).to_owned());
- assert!(tell_pos_pre_read == set_cursor);
- assert!(tell_pos_post_read == message.len() as u64);
- })
-
- test!(fn file_test_io_seek_and_write() {
- let initial_msg = "food-is-yummy";
- let overwrite_msg = "-the-bar!!";
- let final_msg = "foo-the-bar!!";
- let seek_idx = 3;
- let mut read_mem = [0, .. 13];
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
- {
- let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(initial_msg.as_bytes());
- rw_stream.seek(seek_idx as i64, SeekSet);
- rw_stream.write(overwrite_msg.as_bytes());
- }
- {
- let mut read_stream = File::open_mode(filename, Open, Read);
- read_stream.read(read_mem);
- }
- unlink(filename);
- let read_str = str::from_utf8(read_mem);
- assert!(read_str == final_msg.to_owned());
- })
-
- test!(fn file_test_io_seek_shakedown() {
- use std::str; // 01234567890123
- let initial_msg = "qwer-asdf-zxcv";
- let chunk_one = "qwer";
- let chunk_two = "asdf";
- let chunk_three = "zxcv";
- let mut read_mem = [0, .. 4];
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
- {
- let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(initial_msg.as_bytes());
- }
- {
- let mut read_stream = File::open_mode(filename, Open, Read);
-
- read_stream.seek(-4, SeekEnd);
- read_stream.read(read_mem);
- let read_str = str::from_utf8(read_mem);
- assert!(read_str == chunk_three.to_owned());
-
- read_stream.seek(-9, SeekCur);
- read_stream.read(read_mem);
- let read_str = str::from_utf8(read_mem);
- assert!(read_str == chunk_two.to_owned());
-
- read_stream.seek(0, SeekSet);
- read_stream.read(read_mem);
- let read_str = str::from_utf8(read_mem);
- assert!(read_str == chunk_one.to_owned());
- }
- unlink(filename);
- })
-
- test!(fn file_test_stat_is_correct_on_is_file() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_stat_correct_on_is_file.txt");
- {
- let mut fs = File::open_mode(filename, Open, ReadWrite);
- let msg = "hw";
- fs.write(msg.as_bytes());
- }
- let stat_res = stat(filename);
- assert_eq!(stat_res.kind, io::TypeFile);
- unlink(filename);
- })
-
- test!(fn file_test_stat_is_correct_on_is_dir() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_stat_correct_on_is_dir");
- mkdir(filename, io::UserRWX);
- let stat_res = filename.stat();
- assert!(stat_res.kind == io::TypeDirectory);
- rmdir(filename);
- })
-
- test!(fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("fileinfo_false_on_dir");
- mkdir(dir, io::UserRWX);
- assert!(dir.is_file() == false);
- rmdir(dir);
- })
-
- test!(fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
- let tmpdir = tmpdir();
- let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
- File::create(file).write(bytes!("foo"));
- assert!(file.exists());
- unlink(file);
- assert!(!file.exists());
- })
-
- test!(fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("before_and_after_dir");
- assert!(!dir.exists());
- mkdir(dir, io::UserRWX);
- assert!(dir.exists());
- assert!(dir.is_dir());
- rmdir(dir);
- assert!(!dir.exists());
- })
-
- test!(fn file_test_directoryinfo_readdir() {
- use std::str;
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("di_readdir");
- mkdir(dir, io::UserRWX);
- let prefix = "foo";
- for n in range(0,3) {
- let f = dir.join(format!("{}.txt", n));
- let mut w = File::create(&f);
- let msg_str = (prefix + n.to_str().to_owned()).to_owned();
- let msg = msg_str.as_bytes();
- w.write(msg);
- }
- let files = readdir(dir);
- let mut mem = [0u8, .. 4];
- for f in files.iter() {
- {
- let n = f.filestem_str();
- File::open(f).read(mem);
- let read_str = str::from_utf8(mem);
- let expected = match n {
- None|Some("") => fail!("really shouldn't happen.."),
- Some(n) => prefix+n
- };
- assert!(expected == read_str);
- }
- unlink(f);
- }
- rmdir(dir);
- })
-
- test!(fn recursive_mkdir_slash() {
- mkdir_recursive(&Path::new("/"), io::UserRWX);
- })
-
- test!(fn unicode_path_is_dir() {
- assert!(Path::new(".").is_dir());
- assert!(!Path::new("test/stdtest/fs.rs").is_dir());
-
- let tmpdir = tmpdir();
-
- let mut dirpath = tmpdir.clone();
- dirpath.push(format!("test-가一ー你好"));
- mkdir(&dirpath, io::UserRWX);
- assert!(dirpath.is_dir());
-
- let mut filepath = dirpath;
- filepath.push("unicode-file-\uac00\u4e00\u30fc\u4f60\u597d.rs");
- File::create(&filepath); // ignore return; touch only
- assert!(!filepath.is_dir());
- assert!(filepath.exists());
- })
-
- test!(fn unicode_path_exists() {
- assert!(Path::new(".").exists());
- assert!(!Path::new("test/nonexistent-bogus-path").exists());
-
- let tmpdir = tmpdir();
- let unicode = tmpdir.clone();
- let unicode = unicode.join(format!("test-각丁ー再见"));
- mkdir(&unicode, io::UserRWX);
- assert!(unicode.exists());
- assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
- })
-
- test!(fn copy_file_does_not_exist() {
- let from = Path::new("test/nonexistent-bogus-path");
- let to = Path::new("test/other-bogus-path");
- match io::result(|| copy(&from, &to)) {
- Ok(..) => fail!(),
- Err(..) => {
- assert!(!from.exists());
- assert!(!to.exists());
- }
- }
- })
-
- test!(fn copy_file_ok() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- File::create(&input).write(bytes!("hello"));
- copy(&input, &out);
- let contents = File::open(&out).read_to_end();
- assert_eq!(contents.as_slice(), bytes!("hello"));
-
- assert_eq!(input.stat().perm, out.stat().perm);
- })
-
- test!(fn copy_file_dst_dir() {
- let tmpdir = tmpdir();
- let out = tmpdir.join("out");
-
- File::create(&out);
- match io::result(|| copy(&out, &*tmpdir)) {
- Ok(..) => fail!(), Err(..) => {}
- }
- })
-
- test!(fn copy_file_dst_exists() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in");
- let output = tmpdir.join("out");
-
- File::create(&input).write("foo".as_bytes());
- File::create(&output).write("bar".as_bytes());
- copy(&input, &output);
-
- assert_eq!(File::open(&output).read_to_end(),
- (bytes!("foo")).to_owned());
- })
-
- test!(fn copy_file_src_dir() {
- let tmpdir = tmpdir();
- let out = tmpdir.join("out");
-
- match io::result(|| copy(&*tmpdir, &out)) {
- Ok(..) => fail!(), Err(..) => {}
- }
- assert!(!out.exists());
- })
-
- test!(fn copy_file_preserves_perm_bits() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- File::create(&input);
- chmod(&input, io::UserRead);
- copy(&input, &out);
- assert!(out.stat().perm & io::UserWrite == 0);
-
- chmod(&input, io::UserFile);
- chmod(&out, io::UserFile);
- })
-
- #[cfg(not(windows))] // FIXME(#10264) operation not permitted?
- test!(fn symlinks_work() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- File::create(&input).write("foobar".as_bytes());
- symlink(&input, &out);
- if cfg!(not(windows)) {
- assert_eq!(lstat(&out).kind, io::TypeSymlink);
- }
- assert_eq!(stat(&out).size, stat(&input).size);
- assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned());
- })
-
- #[cfg(not(windows))] // apparently windows doesn't like symlinks
- test!(fn symlink_noexist() {
- let tmpdir = tmpdir();
- // symlinks can point to things that don't exist
- symlink(&tmpdir.join("foo"), &tmpdir.join("bar"));
- assert!(readlink(&tmpdir.join("bar")).unwrap() == tmpdir.join("foo"));
- })
-
- test!(fn readlink_not_symlink() {
- let tmpdir = tmpdir();
- match io::result(|| readlink(&*tmpdir)) {
- Ok(..) => fail!("wanted a failure"),
- Err(..) => {}
- }
- })
-
- test!(fn links_work() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- File::create(&input).write("foobar".as_bytes());
- link(&input, &out);
- if cfg!(not(windows)) {
- assert_eq!(lstat(&out).kind, io::TypeFile);
- assert_eq!(stat(&out).unstable.nlink, 2);
- }
- assert_eq!(stat(&out).size, stat(&input).size);
- assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned());
-
- // can't link to yourself
- match io::result(|| link(&input, &input)) {
- Ok(..) => fail!("wanted a failure"),
- Err(..) => {}
- }
- // can't link to something that doesn't exist
- match io::result(|| link(&tmpdir.join("foo"), &tmpdir.join("bar"))) {
- Ok(..) => fail!("wanted a failure"),
- Err(..) => {}
- }
- })
-
- test!(fn chmod_works() {
- let tmpdir = tmpdir();
- let file = tmpdir.join("in.txt");
-
- File::create(&file);
- assert!(stat(&file).perm & io::UserWrite == io::UserWrite);
- chmod(&file, io::UserRead);
- assert!(stat(&file).perm & io::UserWrite == 0);
-
- match io::result(|| chmod(&tmpdir.join("foo"), io::UserRWX)) {
- Ok(..) => fail!("wanted a failure"),
- Err(..) => {}
- }
-
- chmod(&file, io::UserFile);
- })
-
- test!(fn sync_doesnt_kill_anything() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("in.txt");
-
- let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
- file.fsync();
- file.datasync();
- file.write(bytes!("foo"));
- file.fsync();
- file.datasync();
- util::ignore(file);
- })
-
- test!(fn truncate_works() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("in.txt");
-
- let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
- file.write(bytes!("foo"));
- file.fsync();
-
- // Do some simple things with truncation
- assert_eq!(stat(&path).size, 3);
- file.truncate(10);
- assert_eq!(stat(&path).size, 10);
- file.write(bytes!("bar"));
- file.fsync();
- assert_eq!(stat(&path).size, 10);
- assert_eq!(File::open(&path).read_to_end(),
- (bytes!("foobar", 0, 0, 0, 0)).to_owned());
-
- // Truncate to a smaller length, don't seek, and then write something.
- // Ensure that the intermediate zeroes are all filled in (we're seeked
- // past the end of the file).
- file.truncate(2);
- assert_eq!(stat(&path).size, 2);
- file.write(bytes!("wut"));
- file.fsync();
- assert_eq!(stat(&path).size, 9);
- assert_eq!(File::open(&path).read_to_end(),
- (bytes!("fo", 0, 0, 0, 0, "wut")).to_owned());
- util::ignore(file);
- })
-
- test!(fn open_flavors() {
- let tmpdir = tmpdir();
-
- match io::result(|| File::open_mode(&tmpdir.join("a"), io::Open,
- io::Read)) {
- Ok(..) => fail!(), Err(..) => {}
- }
- File::open_mode(&tmpdir.join("b"), io::Open, io::Write).unwrap();
- File::open_mode(&tmpdir.join("c"), io::Open, io::ReadWrite).unwrap();
- File::open_mode(&tmpdir.join("d"), io::Append, io::Write).unwrap();
- File::open_mode(&tmpdir.join("e"), io::Append, io::ReadWrite).unwrap();
- File::open_mode(&tmpdir.join("f"), io::Truncate, io::Write).unwrap();
- File::open_mode(&tmpdir.join("g"), io::Truncate, io::ReadWrite).unwrap();
-
- File::create(&tmpdir.join("h")).write("foo".as_bytes());
- File::open_mode(&tmpdir.join("h"), io::Open, io::Read).unwrap();
- {
- let mut f = File::open_mode(&tmpdir.join("h"), io::Open,
- io::Read).unwrap();
- match io::result(|| f.write("wut".as_bytes())) {
- Ok(..) => fail!(), Err(..) => {}
- }
- }
- assert_eq!(stat(&tmpdir.join("h")).size, 3);
- {
- let mut f = File::open_mode(&tmpdir.join("h"), io::Append,
- io::Write).unwrap();
- f.write("bar".as_bytes());
- }
- assert_eq!(stat(&tmpdir.join("h")).size, 6);
- {
- let mut f = File::open_mode(&tmpdir.join("h"), io::Truncate,
- io::Write).unwrap();
- f.write("bar".as_bytes());
- }
- assert_eq!(stat(&tmpdir.join("h")).size, 3);
- })
-
- #[test]
- fn utime() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("a");
- File::create(&path);
-
- change_file_times(&path, 1000, 2000);
- assert_eq!(path.stat().accessed, 1000);
- assert_eq!(path.stat().modified, 2000);
- }
-
- #[test]
- fn utime_noexist() {
- let tmpdir = tmpdir();
-
- match io::result(|| change_file_times(&tmpdir.join("a"), 100, 200)) {
- Ok(..) => fail!(),
- Err(..) => {}
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Readers and Writers for in-memory buffers
-//!
-//! # XXX
-//!
-//! * Should probably have something like this for strings.
-//! * Should they implement Closable? Would take extra state.
-use cmp::max;
-use cmp::min;
-use prelude::*;
-use super::*;
-use vec;
-
-/// Writes to an owned, growable byte vector
-pub struct MemWriter {
- priv buf: ~[u8],
- priv pos: uint,
-}
-
-impl MemWriter {
- pub fn new() -> MemWriter {
- MemWriter { buf: vec::with_capacity(128), pos: 0 }
- }
-}
-
-impl Writer for MemWriter {
- fn write(&mut self, buf: &[u8]) {
- // Make sure the internal buffer is as least as big as where we
- // currently are
- let difference = self.pos as i64 - self.buf.len() as i64;
- if difference > 0 {
- self.buf.grow(difference as uint, &0);
- }
-
- // Figure out what bytes will be used to overwrite what's currently
- // there (left), and what will be appended on the end (right)
- let cap = self.buf.len() - self.pos;
- let (left, right) = if cap <= buf.len() {
- (buf.slice_to(cap), buf.slice_from(cap))
- } else {
- (buf, &[])
- };
-
- // Do the necessary writes
- if left.len() > 0 {
- vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos),
- left, left.len());
- }
- if right.len() > 0 {
- self.buf.push_all(right);
- }
-
- // Bump us forward
- self.pos += buf.len();
- }
-}
-
-// FIXME(#10432)
-impl Seek for MemWriter {
- fn tell(&self) -> u64 { self.pos as u64 }
-
- fn seek(&mut self, pos: i64, style: SeekStyle) {
- // compute offset as signed and clamp to prevent overflow
- let offset = match style {
- SeekSet => { 0 }
- SeekEnd => { self.buf.len() }
- SeekCur => { self.pos }
- } as i64;
-
- self.pos = max(0, offset+pos) as uint;
- }
-}
-
-impl Decorator<~[u8]> for MemWriter {
- fn inner(self) -> ~[u8] { self.buf }
- fn inner_ref<'a>(&'a self) -> &'a ~[u8] { &self.buf }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] { &mut self.buf }
-}
-
-/// Reads from an owned byte vector
-pub struct MemReader {
- priv buf: ~[u8],
- priv pos: uint
-}
-
-impl MemReader {
- pub fn new(buf: ~[u8]) -> MemReader {
- MemReader {
- buf: buf,
- pos: 0
- }
- }
-}
-
-impl Reader for MemReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- { if self.eof() { return None; } }
-
- let write_len = min(buf.len(), self.buf.len() - self.pos);
- {
- let input = self.buf.slice(self.pos, self.pos + write_len);
- let output = buf.mut_slice(0, write_len);
- assert_eq!(input.len(), output.len());
- vec::bytes::copy_memory(output, input, write_len);
- }
- self.pos += write_len;
- assert!(self.pos <= self.buf.len());
-
- return Some(write_len);
- }
-
- fn eof(&mut self) -> bool { self.pos == self.buf.len() }
-}
-
-impl Seek for MemReader {
- fn tell(&self) -> u64 { self.pos as u64 }
- fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
-}
-
-impl Buffer for MemReader {
- fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
- fn consume(&mut self, amt: uint) { self.pos += amt; }
-}
-
-impl Decorator<~[u8]> for MemReader {
- fn inner(self) -> ~[u8] { self.buf }
- fn inner_ref<'a>(&'a self) -> &'a ~[u8] { &self.buf }
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] { &mut self.buf }
-}
-
-
-/// Writes to a fixed-size byte slice
-///
-/// If a write will not fit in the buffer, it raises the `io_error`
-/// condition and does not write any data.
-pub struct BufWriter<'self> {
- priv buf: &'self mut [u8],
- priv pos: uint
-}
-
-impl<'self> BufWriter<'self> {
- pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
- BufWriter {
- buf: buf,
- pos: 0
- }
- }
-}
-
-impl<'self> Writer for BufWriter<'self> {
- fn write(&mut self, buf: &[u8]) {
- // raises a condition if the entire write does not fit in the buffer
- let max_size = self.buf.len();
- if self.pos >= max_size || (self.pos + buf.len()) > max_size {
- io_error::cond.raise(IoError {
- kind: OtherIoError,
- desc: "Trying to write past end of buffer",
- detail: None
- });
- return;
- }
-
- vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos),
- buf, buf.len());
- self.pos += buf.len();
- }
-}
-
-// FIXME(#10432)
-impl<'self> Seek for BufWriter<'self> {
- fn tell(&self) -> u64 { self.pos as u64 }
-
- fn seek(&mut self, pos: i64, style: SeekStyle) {
- // compute offset as signed and clamp to prevent overflow
- let offset = match style {
- SeekSet => { 0 }
- SeekEnd => { self.buf.len() }
- SeekCur => { self.pos }
- } as i64;
-
- self.pos = max(0, offset+pos) as uint;
- }
-}
-
-
-/// Reads from a fixed-size byte slice
-pub struct BufReader<'self> {
- priv buf: &'self [u8],
- priv pos: uint
-}
-
-impl<'self> BufReader<'self> {
- pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
- BufReader {
- buf: buf,
- pos: 0
- }
- }
-}
-
-impl<'self> Reader for BufReader<'self> {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- { if self.eof() { return None; } }
-
- let write_len = min(buf.len(), self.buf.len() - self.pos);
- {
- let input = self.buf.slice(self.pos, self.pos + write_len);
- let output = buf.mut_slice(0, write_len);
- assert_eq!(input.len(), output.len());
- vec::bytes::copy_memory(output, input, write_len);
- }
- self.pos += write_len;
- assert!(self.pos <= self.buf.len());
-
- return Some(write_len);
- }
-
- fn eof(&mut self) -> bool { self.pos == self.buf.len() }
-}
-
-impl<'self> Seek for BufReader<'self> {
- fn tell(&self) -> u64 { self.pos as u64 }
-
- fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
-}
-
-impl<'self> Buffer for BufReader<'self> {
- fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
- fn consume(&mut self, amt: uint) { self.pos += amt; }
-}
-
-///Calls a function with a MemWriter and returns
-///the writer's stored vector.
-pub fn with_mem_writer(writeFn: |&mut MemWriter|) -> ~[u8] {
- let mut writer = MemWriter::new();
- writeFn(&mut writer);
- writer.inner()
-}
-
-#[cfg(test)]
-mod test {
- use prelude::*;
- use super::*;
- use io::*;
-
- #[test]
- fn test_mem_writer() {
- let mut writer = MemWriter::new();
- assert_eq!(writer.tell(), 0);
- writer.write([0]);
- assert_eq!(writer.tell(), 1);
- writer.write([1, 2, 3]);
- writer.write([4, 5, 6, 7]);
- assert_eq!(writer.tell(), 8);
- assert_eq!(*writer.inner_ref(), ~[0, 1, 2, 3, 4, 5, 6, 7]);
-
- writer.seek(0, SeekSet);
- assert_eq!(writer.tell(), 0);
- writer.write([3, 4]);
- assert_eq!(*writer.inner_ref(), ~[3, 4, 2, 3, 4, 5, 6, 7]);
-
- writer.seek(1, SeekCur);
- writer.write([0, 1]);
- assert_eq!(*writer.inner_ref(), ~[3, 4, 2, 0, 1, 5, 6, 7]);
-
- writer.seek(-1, SeekEnd);
- writer.write([1, 2]);
- assert_eq!(*writer.inner_ref(), ~[3, 4, 2, 0, 1, 5, 6, 1, 2]);
-
- writer.seek(1, SeekEnd);
- writer.write([1]);
- assert_eq!(*writer.inner_ref(), ~[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]);
- }
-
- #[test]
- fn test_buf_writer() {
- let mut buf = [0 as u8, ..8];
- {
- let mut writer = BufWriter::new(buf);
- assert_eq!(writer.tell(), 0);
- writer.write([0]);
- assert_eq!(writer.tell(), 1);
- writer.write([1, 2, 3]);
- writer.write([4, 5, 6, 7]);
- assert_eq!(writer.tell(), 8);
- }
- assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7]);
- }
-
- #[test]
- fn test_buf_writer_seek() {
- let mut buf = [0 as u8, ..8];
- {
- let mut writer = BufWriter::new(buf);
- assert_eq!(writer.tell(), 0);
- writer.write([1]);
- assert_eq!(writer.tell(), 1);
-
- writer.seek(2, SeekSet);
- assert_eq!(writer.tell(), 2);
- writer.write([2]);
- assert_eq!(writer.tell(), 3);
-
- writer.seek(-2, SeekCur);
- assert_eq!(writer.tell(), 1);
- writer.write([3]);
- assert_eq!(writer.tell(), 2);
-
- writer.seek(-1, SeekEnd);
- assert_eq!(writer.tell(), 7);
- writer.write([4]);
- assert_eq!(writer.tell(), 8);
-
- }
- assert_eq!(buf, [1, 3, 2, 0, 0, 0, 0, 4]);
- }
-
- #[test]
- fn test_buf_writer_error() {
- let mut buf = [0 as u8, ..2];
- let mut writer = BufWriter::new(buf);
- writer.write([0]);
-
- let mut called = false;
- io_error::cond.trap(|err| {
- assert_eq!(err.kind, OtherIoError);
- called = true;
- }).inside(|| {
- writer.write([0, 0]);
- });
- assert!(called);
- }
-
- #[test]
- fn test_mem_reader() {
- let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
- let mut buf = [];
- assert_eq!(reader.read(buf), Some(0));
- assert_eq!(reader.tell(), 0);
- let mut buf = [0];
- assert_eq!(reader.read(buf), Some(1));
- assert_eq!(reader.tell(), 1);
- assert_eq!(buf, [0]);
- let mut buf = [0, ..4];
- assert_eq!(reader.read(buf), Some(4));
- assert_eq!(reader.tell(), 5);
- assert_eq!(buf, [1, 2, 3, 4]);
- assert_eq!(reader.read(buf), Some(3));
- assert_eq!(buf.slice(0, 3), [5, 6, 7]);
- assert!(reader.eof());
- assert_eq!(reader.read(buf), None);
- assert!(reader.eof());
- }
-
- #[test]
- fn test_buf_reader() {
- let in_buf = ~[0, 1, 2, 3, 4, 5, 6, 7];
- let mut reader = BufReader::new(in_buf);
- let mut buf = [];
- assert_eq!(reader.read(buf), Some(0));
- assert_eq!(reader.tell(), 0);
- let mut buf = [0];
- assert_eq!(reader.read(buf), Some(1));
- assert_eq!(reader.tell(), 1);
- assert_eq!(buf, [0]);
- let mut buf = [0, ..4];
- assert_eq!(reader.read(buf), Some(4));
- assert_eq!(reader.tell(), 5);
- assert_eq!(buf, [1, 2, 3, 4]);
- assert_eq!(reader.read(buf), Some(3));
- assert_eq!(buf.slice(0, 3), [5, 6, 7]);
- assert!(reader.eof());
- assert_eq!(reader.read(buf), None);
- assert!(reader.eof());
- }
-
- #[test]
- fn test_with_mem_writer() {
- let buf = with_mem_writer(|wr| wr.write([1,2,3,4,5,6,7]));
- assert_eq!(buf, ~[1,2,3,4,5,6,7]);
- }
-
- #[test]
- fn test_read_char() {
- let mut r = BufReader::new(bytes!("Việt"));
- assert_eq!(r.read_char(), Some('V'));
- assert_eq!(r.read_char(), Some('i'));
- assert_eq!(r.read_char(), Some('ệ'));
- assert_eq!(r.read_char(), Some('t'));
- assert_eq!(r.read_char(), None);
- }
-
- #[test]
- fn test_read_bad_char() {
- let mut r = BufReader::new(bytes!(0x80));
- assert_eq!(r.read_char(), None);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! Synchronous I/O
-
-This module defines the Rust interface for synchronous I/O.
-It models byte-oriented input and output with the Reader and Writer traits.
-Types that implement both `Reader` and `Writer` are called 'streams',
-and automatically implement the `Stream` trait.
-Implementations are provided for common I/O streams like
-file, TCP, UDP, Unix domain sockets.
-Readers and Writers may be composed to add capabilities like string
-parsing, encoding, and compression.
-
-# Examples
-
-Some examples of obvious things you might want to do
-
-* Read lines from stdin
-
- for stdin().each_line |line| {
- println(line)
- }
-
-* Read a complete file to a string, (converting newlines?)
-
- let contents = File::open("message.txt").read_to_str(); // read_to_str??
-
-* Write a line to a file
-
- let file = File::open("message.txt", Create, Write);
- file.write_line("hello, file!");
-
-* Iterate over the lines of a file
-
- File::open("message.txt").each_line(|line| {
- println(line)
- })
-
-* Pull the lines of a file into a vector of strings
-
- let lines = File::open("message.txt").lines().to_vec();
-
-* Make an simple HTTP request
-
- let socket = TcpStream::open("localhost:8080");
- socket.write_line("GET / HTTP/1.0");
- socket.write_line("");
- let response = socket.read_to_end();
-
-* Connect based on URL? Requires thinking about where the URL type lives
- and how to make protocol handlers extensible, e.g. the "tcp" protocol
- yields a `TcpStream`.
-
- connect("tcp://localhost:8080");
-
-# Terms
-
-* Reader - An I/O source, reads bytes into a buffer
-* Writer - An I/O sink, writes bytes from a buffer
-* Stream - Typical I/O sources like files and sockets are both Readers and Writers,
- and are collectively referred to a `streams`.
-* Decorator - A Reader or Writer that composes with others to add additional capabilities
- such as encoding or decoding
-
-# Blocking and synchrony
-
-When discussing I/O you often hear the terms 'synchronous' and
-'asynchronous', along with 'blocking' and 'non-blocking' compared and
-contrasted. A synchronous I/O interface performs each I/O operation to
-completion before proceeding to the next. Synchronous interfaces are
-usually used in imperative style as a sequence of commands. An
-asynchronous interface allows multiple I/O requests to be issued
-simultaneously, without waiting for each to complete before proceeding
-to the next.
-
-Asynchronous interfaces are used to achieve 'non-blocking' I/O. In
-traditional single-threaded systems, performing a synchronous I/O
-operation means that the program stops all activity (it 'blocks')
-until the I/O is complete. Blocking is bad for performance when
-there are other computations that could be done.
-
-Asynchronous interfaces are most often associated with the callback
-(continuation-passing) style popularised by node.js. Such systems rely
-on all computations being run inside an event loop which maintains a
-list of all pending I/O events; when one completes the registered
-callback is run and the code that made the I/O request continues.
-Such interfaces achieve non-blocking at the expense of being more
-difficult to reason about.
-
-Rust's I/O interface is synchronous - easy to read - and non-blocking by default.
-
-Remember that Rust tasks are 'green threads', lightweight threads that
-are multiplexed onto a single operating system thread. If that system
-thread blocks then no other task may proceed. Rust tasks are
-relatively cheap to create, so as long as other tasks are free to
-execute then non-blocking code may be written by simply creating a new
-task.
-
-When discussing blocking in regards to Rust's I/O model, we are
-concerned with whether performing I/O blocks other Rust tasks from
-proceeding. In other words, when a task calls `read`, it must then
-wait (or 'sleep', or 'block') until the call to `read` is complete.
-During this time, other tasks may or may not be executed, depending on
-how `read` is implemented.
-
-
-Rust's default I/O implementation is non-blocking; by cooperating
-directly with the task scheduler it arranges to never block progress
-of *other* tasks. Under the hood, Rust uses asynchronous I/O via a
-per-scheduler (and hence per-thread) event loop. Synchronous I/O
-requests are implemented by descheduling the running task and
-performing an asynchronous request; the task is only resumed once the
-asynchronous request completes.
-
-For blocking (but possibly more efficient) implementations, look
-in the `io::native` module.
-
-# Error Handling
-
-I/O is an area where nearly every operation can result in unexpected
-errors. It should allow errors to be handled efficiently.
-It needs to be convenient to use I/O when you don't care
-about dealing with specific errors.
-
-Rust's I/O employs a combination of techniques to reduce boilerplate
-while still providing feedback about errors. The basic strategy:
-
-* Errors are fatal by default, resulting in task failure
-* Errors raise the `io_error` condition which provides an opportunity to inspect
- an IoError object containing details.
-* Return values must have a sensible null or zero value which is returned
- if a condition is handled successfully. This may be an `Option`, an empty
- vector, or other designated error value.
-* Common traits are implemented for `Option`, e.g. `impl<R: Reader> Reader for Option<R>`,
- so that nullable values do not have to be 'unwrapped' before use.
-
-These features combine in the API to allow for expressions like
-`File::new("diary.txt").write_line("met a girl")` without having to
-worry about whether "diary.txt" exists or whether the write
-succeeds. As written, if either `new` or `write_line` encounters
-an error the task will fail.
-
-If you wanted to handle the error though you might write
-
- let mut error = None;
- do io_error::cond(|e: IoError| {
- error = Some(e);
- }).in {
- File::new("diary.txt").write_line("met a girl");
- }
-
- if error.is_some() {
- println("failed to write my diary");
- }
-
-XXX: Need better condition handling syntax
-
-In this case the condition handler will have the opportunity to
-inspect the IoError raised by either the call to `new` or the call to
-`write_line`, but then execution will continue.
-
-So what actually happens if `new` encounters an error? To understand
-that it's important to know that what `new` returns is not a `File`
-but an `Option<File>`. If the file does not open, and the condition
-is handled, then `new` will simply return `None`. Because there is an
-implementation of `Writer` (the trait required ultimately required for
-types to implement `write_line`) there is no need to inspect or unwrap
-the `Option<File>` and we simply call `write_line` on it. If `new`
-returned a `None` then the followup call to `write_line` will also
-raise an error.
-
-## Concerns about this strategy
-
-This structure will encourage a programming style that is prone
-to errors similar to null pointer dereferences.
-In particular code written to ignore errors and expect conditions to be unhandled
-will start passing around null or zero objects when wrapped in a condition handler.
-
-* XXX: How should we use condition handlers that return values?
-* XXX: Should EOF raise default conditions when EOF is not an error?
-
-# Issues with i/o scheduler affinity, work stealing, task pinning
-
-# Resource management
-
-* `close` vs. RAII
-
-# Paths, URLs and overloaded constructors
-
-
-
-# Scope
-
-In scope for core
-
-* Url?
-
-Some I/O things don't belong in core
-
- - url
- - net - `fn connect`
- - http
- - flate
-
-Out of scope
-
-* Async I/O. We'll probably want it eventually
-
-
-# XXX Questions and issues
-
-* Should default constructors take `Path` or `&str`? `Path` makes simple cases verbose.
- Overloading would be nice.
-* Add overloading for Path and &str and Url &str
-* stdin/err/out
-* print, println, etc.
-* fsync
-* relationship with filesystem querying, Directory, File types etc.
-* Rename Reader/Writer to ByteReader/Writer, make Reader/Writer generic?
-* Can Port and Chan be implementations of a generic Reader<T>/Writer<T>?
-* Trait for things that are both readers and writers, Stream?
-* How to handle newline conversion
-* String conversion
-* open vs. connect for generic stream opening
-* Do we need `close` at all? dtors might be good enough
-* How does I/O relate to the Iterator trait?
-* std::base64 filters
-* Using conditions is a big unknown since we don't have much experience with them
-* Too many uses of OtherIoError
-
-*/
-
-#[allow(missing_doc)];
-
-use cast;
-use container::Container;
-use int;
-use iter::Iterator;
-use option::{Option, Some, None};
-use path::Path;
-use result::{Ok, Err, Result};
-use str;
-use str::{StrSlice, OwnedStr};
-use to_str::ToStr;
-use uint;
-use unstable::finally::Finally;
-use vec::{OwnedVector, MutableVector, ImmutableVector, OwnedCopyableVector};
-use vec;
-
-// Reexports
-pub use self::stdio::stdin;
-pub use self::stdio::stdout;
-pub use self::stdio::stderr;
-pub use self::stdio::print;
-pub use self::stdio::println;
-
-pub use self::fs::File;
-pub use self::timer::Timer;
-pub use self::net::ip::IpAddr;
-pub use self::net::tcp::TcpListener;
-pub use self::net::tcp::TcpStream;
-pub use self::net::udp::UdpStream;
-pub use self::pipe::PipeStream;
-pub use self::process::Process;
-
-/// Synchronous, non-blocking filesystem operations.
-pub mod fs;
-
-/// Synchronous, in-memory I/O.
-pub mod pipe;
-
-/// Child process management.
-pub mod process;
-
-/// Synchronous, non-blocking network I/O.
-pub mod net;
-
-/// Readers and Writers for memory buffers and strings.
-pub mod mem;
-
-/// Non-blocking access to stdin, stdout, stderr
-pub mod stdio;
-
-/// Implementations for Option
-mod option;
-
-/// Basic stream compression. XXX: Belongs with other flate code
-pub mod flate;
-
-/// Interop between byte streams and pipes. Not sure where it belongs
-pub mod comm_adapters;
-
-/// Extension traits
-pub mod extensions;
-
-/// Basic Timer
-pub mod timer;
-
-/// Buffered I/O wrappers
-pub mod buffered;
-
-pub mod native;
-
-/// Signal handling
-pub mod signal;
-
-/// The default buffer size for various I/O operations
-static DEFAULT_BUF_SIZE: uint = 1024 * 64;
-
-/// The type passed to I/O condition handlers to indicate error
-///
-/// # XXX
-///
-/// Is something like this sufficient? It's kind of archaic
-pub struct IoError {
- kind: IoErrorKind,
- desc: &'static str,
- detail: Option<~str>
-}
-
-// FIXME: #8242 implementing manually because deriving doesn't work for some reason
-impl ToStr for IoError {
- fn to_str(&self) -> ~str {
- let mut s = ~"IoError { kind: ";
- s.push_str(self.kind.to_str());
- s.push_str(", desc: ");
- s.push_str(self.desc);
- s.push_str(", detail: ");
- s.push_str(self.detail.to_str());
- s.push_str(" }");
- s
- }
-}
-
-#[deriving(Eq)]
-pub enum IoErrorKind {
- PreviousIoError,
- OtherIoError,
- EndOfFile,
- FileNotFound,
- PermissionDenied,
- ConnectionFailed,
- Closed,
- ConnectionRefused,
- ConnectionReset,
- ConnectionAborted,
- NotConnected,
- BrokenPipe,
- PathAlreadyExists,
- PathDoesntExist,
- MismatchedFileTypeForOperation,
- ResourceUnavailable,
- IoUnavailable,
-}
-
-// FIXME: #8242 implementing manually because deriving doesn't work for some reason
-impl ToStr for IoErrorKind {
- fn to_str(&self) -> ~str {
- match *self {
- PreviousIoError => ~"PreviousIoError",
- OtherIoError => ~"OtherIoError",
- EndOfFile => ~"EndOfFile",
- FileNotFound => ~"FileNotFound",
- PermissionDenied => ~"PermissionDenied",
- ConnectionFailed => ~"ConnectionFailed",
- Closed => ~"Closed",
- ConnectionRefused => ~"ConnectionRefused",
- ConnectionReset => ~"ConnectionReset",
- NotConnected => ~"NotConnected",
- BrokenPipe => ~"BrokenPipe",
- PathAlreadyExists => ~"PathAlreadyExists",
- PathDoesntExist => ~"PathDoesntExist",
- MismatchedFileTypeForOperation => ~"MismatchedFileTypeForOperation",
- IoUnavailable => ~"IoUnavailable",
- ResourceUnavailable => ~"ResourceUnavailable",
- ConnectionAborted => ~"ConnectionAborted",
- }
- }
-}
-
-// XXX: Can't put doc comments on macros
-// Raised by `I/O` operations on error.
-condition! {
- pub io_error: IoError -> ();
-}
-
-/// Helper for wrapper calls where you want to
-/// ignore any io_errors that might be raised
-pub fn ignore_io_error<T>(cb: || -> T) -> T {
- io_error::cond.trap(|_| {
- // just swallow the error.. downstream users
- // who can make a decision based on a None result
- // won't care
- }).inside(|| cb())
-}
-
-/// Helper for catching an I/O error and wrapping it in a Result object. The
-/// return result will be the last I/O error that happened or the result of the
-/// closure if no error occurred.
-pub fn result<T>(cb: || -> T) -> Result<T, IoError> {
- let mut err = None;
- let ret = io_error::cond.trap(|e| {
- if err.is_none() {
- err = Some(e);
- }
- }).inside(cb);
- match err {
- Some(e) => Err(e),
- None => Ok(ret),
- }
-}
-
-pub trait Reader {
-
- // Only two methods which need to get implemented for this trait
-
- /// Read bytes, up to the length of `buf` and place them in `buf`.
- /// Returns the number of bytes read. The number of bytes read my
- /// be less than the number requested, even 0. Returns `None` on EOF.
- ///
- /// # Failure
- ///
- /// Raises the `io_error` condition on error. If the condition
- /// is handled then no guarantee is made about the number of bytes
- /// read and the contents of `buf`. If the condition is handled
- /// returns `None` (XXX see below).
- ///
- /// # XXX
- ///
- /// * Should raise_default error on eof?
- /// * If the condition is handled it should still return the bytes read,
- /// in which case there's no need to return Option - but then you *have*
- /// to install a handler to detect eof.
- ///
- /// This doesn't take a `len` argument like the old `read`.
- /// Will people often need to slice their vectors to call this
- /// and will that be annoying?
- /// Is it actually possible for 0 bytes to be read successfully?
- fn read(&mut self, buf: &mut [u8]) -> Option<uint>;
-
- /// Return whether the Reader has reached the end of the stream.
- ///
- /// # Example
- ///
- /// let reader = File::open(&Path::new("foo.txt"))
- /// while !reader.eof() {
- /// println(reader.read_line());
- /// }
- ///
- /// # Failure
- ///
- /// Returns `true` on failure.
- fn eof(&mut self) -> bool;
-
- // Convenient helper methods based on the above methods
-
- /// Reads a single byte. Returns `None` on EOF.
- ///
- /// # Failure
- ///
- /// Raises the same conditions as the `read` method. Returns
- /// `None` if the condition is handled.
- fn read_byte(&mut self) -> Option<u8> {
- let mut buf = [0];
- match self.read(buf) {
- Some(0) => {
- debug!("read 0 bytes. trying again");
- self.read_byte()
- }
- Some(1) => Some(buf[0]),
- Some(_) => unreachable!(),
- None => None
- }
- }
-
- /// Reads `len` bytes and appends them to a vector.
- ///
- /// May push fewer than the requested number of bytes on error
- /// or EOF. Returns true on success, false on EOF or error.
- ///
- /// # Failure
- ///
- /// Raises the same conditions as `read`. Additionally raises `io_error`
- /// on EOF. If `io_error` is handled then `push_bytes` may push less
- /// than the requested number of bytes.
- fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) {
- unsafe {
- let start_len = buf.len();
- let mut total_read = 0;
-
- buf.reserve_additional(len);
- vec::raw::set_len(buf, start_len + len);
-
- (|| {
- while total_read < len {
- let len = buf.len();
- let slice = buf.mut_slice(start_len + total_read, len);
- match self.read(slice) {
- Some(nread) => {
- total_read += nread;
- }
- None => {
- io_error::cond.raise(standard_error(EndOfFile));
- break;
- }
- }
- }
- }).finally(|| vec::raw::set_len(buf, start_len + total_read))
- }
- }
-
- /// Reads `len` bytes and gives you back a new vector of length `len`
- ///
- /// # Failure
- ///
- /// Raises the same conditions as `read`. Additionally raises `io_error`
- /// on EOF. If `io_error` is handled then the returned vector may
- /// contain less than the requested number of bytes.
- fn read_bytes(&mut self, len: uint) -> ~[u8] {
- let mut buf = vec::with_capacity(len);
- self.push_bytes(&mut buf, len);
- return buf;
- }
-
- /// Reads all remaining bytes from the stream.
- ///
- /// # Failure
- ///
- /// Raises the same conditions as the `read` method.
- fn read_to_end(&mut self) -> ~[u8] {
- let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE);
- let mut keep_reading = true;
- io_error::cond.trap(|e| {
- if e.kind == EndOfFile {
- keep_reading = false;
- } else {
- io_error::cond.raise(e)
- }
- }).inside(|| {
- while keep_reading {
- self.push_bytes(&mut buf, DEFAULT_BUF_SIZE)
- }
- });
- return buf;
- }
-
- /// Create an iterator that reads a single byte on
- /// each iteration, until EOF.
- ///
- /// # Failure
- ///
- /// Raises the same conditions as the `read` method, for
- /// each call to its `.next()` method.
- /// Ends the iteration if the condition is handled.
- fn bytes(self) -> extensions::ByteIterator<Self> {
- extensions::ByteIterator::new(self)
- }
-
- // Byte conversion helpers
-
- /// Reads `n` little-endian unsigned integer bytes.
- ///
- /// `n` must be between 1 and 8, inclusive.
- fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
- assert!(nbytes > 0 && nbytes <= 8);
-
- let mut val = 0u64;
- let mut pos = 0;
- let mut i = nbytes;
- while i > 0 {
- val += (self.read_u8() as u64) << pos;
- pos += 8;
- i -= 1;
- }
- val
- }
-
- /// Reads `n` little-endian signed integer bytes.
- ///
- /// `n` must be between 1 and 8, inclusive.
- fn read_le_int_n(&mut self, nbytes: uint) -> i64 {
- extend_sign(self.read_le_uint_n(nbytes), nbytes)
- }
-
- /// Reads `n` big-endian unsigned integer bytes.
- ///
- /// `n` must be between 1 and 8, inclusive.
- fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
- assert!(nbytes > 0 && nbytes <= 8);
-
- let mut val = 0u64;
- let mut i = nbytes;
- while i > 0 {
- i -= 1;
- val += (self.read_u8() as u64) << i * 8;
- }
- val
- }
-
- /// Reads `n` big-endian signed integer bytes.
- ///
- /// `n` must be between 1 and 8, inclusive.
- fn read_be_int_n(&mut self, nbytes: uint) -> i64 {
- extend_sign(self.read_be_uint_n(nbytes), nbytes)
- }
-
- /// Reads a little-endian unsigned integer.
- ///
- /// The number of bytes returned is system-dependant.
- fn read_le_uint(&mut self) -> uint {
- self.read_le_uint_n(uint::bytes) as uint
- }
-
- /// Reads a little-endian integer.
- ///
- /// The number of bytes returned is system-dependant.
- fn read_le_int(&mut self) -> int {
- self.read_le_int_n(int::bytes) as int
- }
-
- /// Reads a big-endian unsigned integer.
- ///
- /// The number of bytes returned is system-dependant.
- fn read_be_uint(&mut self) -> uint {
- self.read_be_uint_n(uint::bytes) as uint
- }
-
- /// Reads a big-endian integer.
- ///
- /// The number of bytes returned is system-dependant.
- fn read_be_int(&mut self) -> int {
- self.read_be_int_n(int::bytes) as int
- }
-
- /// Reads a big-endian `u64`.
- ///
- /// `u64`s are 8 bytes long.
- fn read_be_u64(&mut self) -> u64 {
- self.read_be_uint_n(8) as u64
- }
-
- /// Reads a big-endian `u32`.
- ///
- /// `u32`s are 4 bytes long.
- fn read_be_u32(&mut self) -> u32 {
- self.read_be_uint_n(4) as u32
- }
-
- /// Reads a big-endian `u16`.
- ///
- /// `u16`s are 2 bytes long.
- fn read_be_u16(&mut self) -> u16 {
- self.read_be_uint_n(2) as u16
- }
-
- /// Reads a big-endian `i64`.
- ///
- /// `i64`s are 8 bytes long.
- fn read_be_i64(&mut self) -> i64 {
- self.read_be_int_n(8) as i64
- }
-
- /// Reads a big-endian `i32`.
- ///
- /// `i32`s are 4 bytes long.
- fn read_be_i32(&mut self) -> i32 {
- self.read_be_int_n(4) as i32
- }
-
- /// Reads a big-endian `i16`.
- ///
- /// `i16`s are 2 bytes long.
- fn read_be_i16(&mut self) -> i16 {
- self.read_be_int_n(2) as i16
- }
-
- /// Reads a big-endian `f64`.
- ///
- /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
- fn read_be_f64(&mut self) -> f64 {
- unsafe {
- cast::transmute::<u64, f64>(self.read_be_u64())
- }
- }
-
- /// Reads a big-endian `f32`.
- ///
- /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
- fn read_be_f32(&mut self) -> f32 {
- unsafe {
- cast::transmute::<u32, f32>(self.read_be_u32())
- }
- }
-
- /// Reads a little-endian `u64`.
- ///
- /// `u64`s are 8 bytes long.
- fn read_le_u64(&mut self) -> u64 {
- self.read_le_uint_n(8) as u64
- }
-
- /// Reads a little-endian `u32`.
- ///
- /// `u32`s are 4 bytes long.
- fn read_le_u32(&mut self) -> u32 {
- self.read_le_uint_n(4) as u32
- }
-
- /// Reads a little-endian `u16`.
- ///
- /// `u16`s are 2 bytes long.
- fn read_le_u16(&mut self) -> u16 {
- self.read_le_uint_n(2) as u16
- }
-
- /// Reads a little-endian `i64`.
- ///
- /// `i64`s are 8 bytes long.
- fn read_le_i64(&mut self) -> i64 {
- self.read_le_int_n(8) as i64
- }
-
- /// Reads a little-endian `i32`.
- ///
- /// `i32`s are 4 bytes long.
- fn read_le_i32(&mut self) -> i32 {
- self.read_le_int_n(4) as i32
- }
-
- /// Reads a little-endian `i16`.
- ///
- /// `i16`s are 2 bytes long.
- fn read_le_i16(&mut self) -> i16 {
- self.read_le_int_n(2) as i16
- }
-
- /// Reads a little-endian `f64`.
- ///
- /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
- fn read_le_f64(&mut self) -> f64 {
- unsafe {
- cast::transmute::<u64, f64>(self.read_le_u64())
- }
- }
-
- /// Reads a little-endian `f32`.
- ///
- /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
- fn read_le_f32(&mut self) -> f32 {
- unsafe {
- cast::transmute::<u32, f32>(self.read_le_u32())
- }
- }
-
- /// Read a u8.
- ///
- /// `u8`s are 1 byte.
- fn read_u8(&mut self) -> u8 {
- match self.read_byte() {
- Some(b) => b as u8,
- None => 0
- }
- }
-
- /// Read an i8.
- ///
- /// `i8`s are 1 byte.
- fn read_i8(&mut self) -> i8 {
- match self.read_byte() {
- Some(b) => b as i8,
- None => 0
- }
- }
-
-}
-
-impl Reader for ~Reader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.read(buf) }
- fn eof(&mut self) -> bool { self.eof() }
-}
-
-impl<'self> Reader for &'self mut Reader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.read(buf) }
- fn eof(&mut self) -> bool { self.eof() }
-}
-
-fn extend_sign(val: u64, nbytes: uint) -> i64 {
- let shift = (8 - nbytes) * 8;
- (val << shift) as i64 >> shift
-}
-
-pub trait Writer {
- /// Write the given buffer
- ///
- /// # Failure
- ///
- /// Raises the `io_error` condition on error
- fn write(&mut self, buf: &[u8]);
-
- /// Flush this output stream, ensuring that all intermediately buffered
- /// contents reach their destination.
- ///
- /// This is by default a no-op and implementors of the `Writer` trait should
- /// decide whether their stream needs to be buffered or not.
- fn flush(&mut self) {}
-
- /// Write the result of passing n through `int::to_str_bytes`.
- fn write_int(&mut self, n: int) {
- int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
- }
-
- /// Write the result of passing n through `uint::to_str_bytes`.
- fn write_uint(&mut self, n: uint) {
- uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
- }
-
- /// Write a little-endian uint (number of bytes depends on system).
- fn write_le_uint(&mut self, n: uint) {
- extensions::u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
- }
-
- /// Write a little-endian int (number of bytes depends on system).
- fn write_le_int(&mut self, n: int) {
- extensions::u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
- }
-
- /// Write a big-endian uint (number of bytes depends on system).
- fn write_be_uint(&mut self, n: uint) {
- extensions::u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
- }
-
- /// Write a big-endian int (number of bytes depends on system).
- fn write_be_int(&mut self, n: int) {
- extensions::u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
- }
-
- /// Write a big-endian u64 (8 bytes).
- fn write_be_u64(&mut self, n: u64) {
- extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
- }
-
- /// Write a big-endian u32 (4 bytes).
- fn write_be_u32(&mut self, n: u32) {
- extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
- }
-
- /// Write a big-endian u16 (2 bytes).
- fn write_be_u16(&mut self, n: u16) {
- extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
- }
-
- /// Write a big-endian i64 (8 bytes).
- fn write_be_i64(&mut self, n: i64) {
- extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
- }
-
- /// Write a big-endian i32 (4 bytes).
- fn write_be_i32(&mut self, n: i32) {
- extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
- }
-
- /// Write a big-endian i16 (2 bytes).
- fn write_be_i16(&mut self, n: i16) {
- extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
- }
-
- /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
- fn write_be_f64(&mut self, f: f64) {
- unsafe {
- self.write_be_u64(cast::transmute(f))
- }
- }
-
- /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
- fn write_be_f32(&mut self, f: f32) {
- unsafe {
- self.write_be_u32(cast::transmute(f))
- }
- }
-
- /// Write a little-endian u64 (8 bytes).
- fn write_le_u64(&mut self, n: u64) {
- extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
- }
-
- /// Write a little-endian u32 (4 bytes).
- fn write_le_u32(&mut self, n: u32) {
- extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
- }
-
- /// Write a little-endian u16 (2 bytes).
- fn write_le_u16(&mut self, n: u16) {
- extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
- }
-
- /// Write a little-endian i64 (8 bytes).
- fn write_le_i64(&mut self, n: i64) {
- extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
- }
-
- /// Write a little-endian i32 (4 bytes).
- fn write_le_i32(&mut self, n: i32) {
- extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
- }
-
- /// Write a little-endian i16 (2 bytes).
- fn write_le_i16(&mut self, n: i16) {
- extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
- }
-
- /// Write a little-endian IEEE754 double-precision floating-point
- /// (8 bytes).
- fn write_le_f64(&mut self, f: f64) {
- unsafe {
- self.write_le_u64(cast::transmute(f))
- }
- }
-
- /// Write a little-endian IEEE754 single-precision floating-point
- /// (4 bytes).
- fn write_le_f32(&mut self, f: f32) {
- unsafe {
- self.write_le_u32(cast::transmute(f))
- }
- }
-
- /// Write a u8 (1 byte).
- fn write_u8(&mut self, n: u8) {
- self.write([n])
- }
-
- /// Write a i8 (1 byte).
- fn write_i8(&mut self, n: i8) {
- self.write([n as u8])
- }
-}
-
-impl Writer for ~Writer {
- fn write(&mut self, buf: &[u8]) { self.write(buf) }
- fn flush(&mut self) { self.flush() }
-}
-
-impl<'self> Writer for &'self mut Writer {
- fn write(&mut self, buf: &[u8]) { self.write(buf) }
- fn flush(&mut self) { self.flush() }
-}
-
-pub trait Stream: Reader + Writer { }
-
-impl<T: Reader + Writer> Stream for T {}
-
-/// A Buffer is a type of reader which has some form of internal buffering to
-/// allow certain kinds of reading operations to be more optimized than others.
-/// This type extends the `Reader` trait with a few methods that are not
-/// possible to reasonably implement with purely a read interface.
-pub trait Buffer: Reader {
- /// Fills the internal buffer of this object, returning the buffer contents.
- /// Note that none of the contents will be "read" in the sense that later
- /// calling `read` may return the same contents.
- ///
- /// The `consume` function must be called with the number of bytes that are
- /// consumed from this buffer returned to ensure that the bytes are never
- /// returned twice.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered.
- fn fill<'a>(&'a mut self) -> &'a [u8];
-
- /// Tells this buffer that `amt` bytes have been consumed from the buffer,
- /// so they should no longer be returned in calls to `fill` or `read`.
- fn consume(&mut self, amt: uint);
-
- /// Reads the next line of input, interpreted as a sequence of utf-8
- /// encoded unicode codepoints. If a newline is encountered, then the
- /// newline is contained in the returned string.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered. The task will also fail if sequence of bytes leading up to
- /// the newline character are not valid utf-8.
- fn read_line(&mut self) -> Option<~str> {
- self.read_until('\n' as u8).map(str::from_utf8_owned)
- }
-
- /// Reads a sequence of bytes leading up to a specified delimeter. Once the
- /// specified byte is encountered, reading ceases and the bytes up to and
- /// including the delimiter are returned.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered.
- fn read_until(&mut self, byte: u8) -> Option<~[u8]> {
- let mut res = ~[];
- let mut used;
- loop {
- {
- let available = self.fill();
- match available.iter().position(|&b| b == byte) {
- Some(i) => {
- res.push_all(available.slice_to(i + 1));
- used = i + 1;
- break
- }
- None => {
- res.push_all(available);
- used = available.len();
- }
- }
- }
- if used == 0 {
- break
- }
- self.consume(used);
- }
- self.consume(used);
- return if res.len() == 0 {None} else {Some(res)};
- }
-
- /// Reads the next utf8-encoded character from the underlying stream.
- ///
- /// This will return `None` if the following sequence of bytes in the
- /// stream are not a valid utf8-sequence, or if an I/O error is encountered.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered.
- fn read_char(&mut self) -> Option<char> {
- let width = {
- let available = self.fill();
- if available.len() == 0 { return None } // read error
- str::utf8_char_width(available[0])
- };
- if width == 0 { return None } // not uf8
- let mut buf = [0, ..4];
- match self.read(buf.mut_slice_to(width)) {
- Some(n) if n == width => {}
- Some(..) | None => return None // read error
- }
- match str::from_utf8_slice_opt(buf.slice_to(width)) {
- Some(s) => Some(s.char_at(0)),
- None => None
- }
- }
-}
-
-pub enum SeekStyle {
- /// Seek from the beginning of the stream
- SeekSet,
- /// Seek from the end of the stream
- SeekEnd,
- /// Seek from the current position
- SeekCur,
-}
-
-/// # XXX
-/// * Are `u64` and `i64` the right choices?
-pub trait Seek {
- /// Return position of file cursor in the stream
- fn tell(&self) -> u64;
-
- /// Seek to an offset in a stream
- ///
- /// A successful seek clears the EOF indicator.
- ///
- /// # XXX
- ///
- /// * What is the behavior when seeking past the end of a stream?
- fn seek(&mut self, pos: i64, style: SeekStyle);
-}
-
-/// A listener is a value that can consume itself to start listening for connections.
-/// Doing so produces some sort of Acceptor.
-pub trait Listener<T, A: Acceptor<T>> {
- /// Spin up the listener and start queueing incoming connections
- ///
- /// # Failure
- ///
- /// Raises `io_error` condition. If the condition is handled,
- /// then `listen` returns `None`.
- fn listen(self) -> Option<A>;
-}
-
-/// An acceptor is a value that presents incoming connections
-pub trait Acceptor<T> {
- /// Wait for and accept an incoming connection
- ///
- /// # Failure
- /// Raise `io_error` condition. If the condition is handled,
- /// then `accept` returns `None`.
- fn accept(&mut self) -> Option<T>;
-
- /// Create an iterator over incoming connection attempts
- fn incoming<'r>(&'r mut self) -> IncomingIterator<'r, Self> {
- IncomingIterator { inc: self }
- }
-}
-
-/// An infinite iterator over incoming connection attempts.
-/// Calling `next` will block the task until a connection is attempted.
-///
-/// Since connection attempts can continue forever, this iterator always returns Some.
-/// The Some contains another Option representing whether the connection attempt was succesful.
-/// A successful connection will be wrapped in Some.
-/// A failed connection is represented as a None and raises a condition.
-struct IncomingIterator<'self, A> {
- priv inc: &'self mut A,
-}
-
-impl<'self, T, A: Acceptor<T>> Iterator<Option<T>> for IncomingIterator<'self, A> {
- fn next(&mut self) -> Option<Option<T>> {
- Some(self.inc.accept())
- }
-}
-
-/// Common trait for decorator types.
-///
-/// Provides accessors to get the inner, 'decorated' values. The I/O library
-/// uses decorators to add functionality like compression and encryption to I/O
-/// streams.
-///
-/// # XXX
-///
-/// Is this worth having a trait for? May be overkill
-pub trait Decorator<T> {
- /// Destroy the decorator and extract the decorated value
- ///
- /// # XXX
- ///
- /// Because this takes `self' one could never 'undecorate' a Reader/Writer
- /// that has been boxed. Is that ok? This feature is mostly useful for
- /// extracting the buffer from MemWriter
- fn inner(self) -> T;
-
- /// Take an immutable reference to the decorated value
- fn inner_ref<'a>(&'a self) -> &'a T;
-
- /// Take a mutable reference to the decorated value
- fn inner_mut_ref<'a>(&'a mut self) -> &'a mut T;
-}
-
-pub fn standard_error(kind: IoErrorKind) -> IoError {
- match kind {
- PreviousIoError => {
- IoError {
- kind: PreviousIoError,
- desc: "Failing due to a previous I/O error",
- detail: None
- }
- }
- EndOfFile => {
- IoError {
- kind: EndOfFile,
- desc: "End of file",
- detail: None
- }
- }
- IoUnavailable => {
- IoError {
- kind: IoUnavailable,
- desc: "I/O is unavailable",
- detail: None
- }
- }
- _ => fail!()
- }
-}
-
-pub fn placeholder_error() -> IoError {
- IoError {
- kind: OtherIoError,
- desc: "Placeholder error. You shouldn't be seeing this",
- detail: None
- }
-}
-
-/// A mode specifies how a file should be opened or created. These modes are
-/// passed to `File::open_mode` and are used to control where the file is
-/// positioned when it is initially opened.
-pub enum FileMode {
- /// Opens a file positioned at the beginning.
- Open,
- /// Opens a file positioned at EOF.
- Append,
- /// Opens a file, truncating it if it already exists.
- Truncate,
-}
-
-/// Access permissions with which the file should be opened. `File`s
-/// opened with `Read` will raise an `io_error` condition if written to.
-pub enum FileAccess {
- Read,
- Write,
- ReadWrite,
-}
-
-/// Different kinds of files which can be identified by a call to stat
-#[deriving(Eq)]
-pub enum FileType {
- TypeFile,
- TypeDirectory,
- TypeNamedPipe,
- TypeBlockSpecial,
- TypeSymlink,
- TypeUnknown,
-}
-
-pub struct FileStat {
- /// The path that this stat structure is describing
- path: Path,
- /// The size of the file, in bytes
- size: u64,
- /// The kind of file this path points to (directory, file, pipe, etc.)
- kind: FileType,
- /// The file permissions currently on the file
- perm: FilePermission,
-
- // FIXME(#10301): These time fields are pretty useless without an actual
- // time representation, what are the milliseconds relative
- // to?
-
- /// The time that the file was created at, in platform-dependent
- /// milliseconds
- created: u64,
- /// The time that this file was last modified, in platform-dependent
- /// milliseconds
- modified: u64,
- /// The time that this file was last accessed, in platform-dependent
- /// milliseconds
- accessed: u64,
-
- /// Information returned by stat() which is not guaranteed to be
- /// platform-independent. This information may be useful on some platforms,
- /// but it may have different meanings or no meaning at all on other
- /// platforms.
- ///
- /// Usage of this field is discouraged, but if access is desired then the
- /// fields are located here.
- #[unstable]
- unstable: UnstableFileStat,
-}
-
-/// This structure represents all of the possible information which can be
-/// returned from a `stat` syscall which is not contained in the `FileStat`
-/// structure. This information is not necessarily platform independent, and may
-/// have different meanings or no meaning at all on some platforms.
-#[unstable]
-pub struct UnstableFileStat {
- device: u64,
- inode: u64,
- rdev: u64,
- nlink: u64,
- uid: u64,
- gid: u64,
- blksize: u64,
- blocks: u64,
- flags: u64,
- gen: u64,
-}
-
-/// A set of permissions for a file or directory is represented by a set of
-/// flags which are or'd together.
-pub type FilePermission = u32;
-
-// Each permission bit
-pub static UserRead: FilePermission = 0x100;
-pub static UserWrite: FilePermission = 0x080;
-pub static UserExecute: FilePermission = 0x040;
-pub static GroupRead: FilePermission = 0x020;
-pub static GroupWrite: FilePermission = 0x010;
-pub static GroupExecute: FilePermission = 0x008;
-pub static OtherRead: FilePermission = 0x004;
-pub static OtherWrite: FilePermission = 0x002;
-pub static OtherExecute: FilePermission = 0x001;
-
-// Common combinations of these bits
-pub static UserRWX: FilePermission = UserRead | UserWrite | UserExecute;
-pub static GroupRWX: FilePermission = GroupRead | GroupWrite | GroupExecute;
-pub static OtherRWX: FilePermission = OtherRead | OtherWrite | OtherExecute;
-
-/// A set of permissions for user owned files, this is equivalent to 0644 on
-/// unix-like systems.
-pub static UserFile: FilePermission = UserRead | UserWrite | GroupRead | OtherRead;
-/// A set of permissions for user owned directories, this is equivalent to 0755
-/// on unix-like systems.
-pub static UserDir: FilePermission = UserRWX | GroupRead | GroupExecute |
- OtherRead | OtherExecute;
-/// A set of permissions for user owned executables, this is equivalent to 0755
-/// on unix-like systems.
-pub static UserExec: FilePermission = UserDir;
-
-/// A mask for all possible permission bits
-pub static AllPermissions: FilePermission = 0x1ff;
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Blocking posix-based file I/O
-
-#[allow(non_camel_case_types)];
-
-use c_str::CString;
-use io::IoError;
-use io;
-use libc::c_int;
-use libc;
-use ops::Drop;
-use option::{Some, None, Option};
-use os;
-use path::{Path, GenericPath};
-use ptr::RawPtr;
-use result::{Result, Ok, Err};
-use rt::rtio;
-use super::IoResult;
-use unstable::intrinsics;
-use vec::ImmutableVector;
-use vec;
-
-#[cfg(windows)] use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
-#[cfg(windows)] use ptr;
-#[cfg(windows)] use str;
-
-fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
- #[cfg(windows)] static eintr: int = 0; // doesn't matter
- #[cfg(not(windows))] static eintr: int = libc::EINTR as int;
-
- let (data, origamt) = data.as_imm_buf(|data, amt| (data, amt));
- let mut data = data;
- let mut amt = origamt;
- while amt > 0 {
- let mut ret;
- loop {
- ret = f(data, amt);
- if cfg!(not(windows)) { break } // windows has no eintr
- // if we get an eintr, then try again
- if ret != -1 || os::errno() as int != eintr { break }
- }
- if ret == 0 {
- break
- } else if ret != -1 {
- amt -= ret as uint;
- data = unsafe { data.offset(ret as int) };
- } else {
- return ret;
- }
- }
- return (origamt - amt) as i64;
-}
-
-pub type fd_t = libc::c_int;
-
-pub struct FileDesc {
- priv fd: fd_t,
- priv close_on_drop: bool,
-}
-
-impl FileDesc {
- /// Create a `FileDesc` from an open C file descriptor.
- ///
- /// The `FileDesc` will take ownership of the specified file descriptor and
- /// close it upon destruction if the `close_on_drop` flag is true, otherwise
- /// it will not close the file descriptor when this `FileDesc` is dropped.
- ///
- /// Note that all I/O operations done on this object will be *blocking*, but
- /// they do not require the runtime to be active.
- pub fn new(fd: fd_t, close_on_drop: bool) -> FileDesc {
- FileDesc { fd: fd, close_on_drop: close_on_drop }
- }
-
- fn inner_read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
- #[cfg(windows)] type rlen = libc::c_uint;
- #[cfg(not(windows))] type rlen = libc::size_t;
- let ret = keep_going(buf, |buf, len| {
- unsafe {
- libc::read(self.fd, buf as *mut libc::c_void, len as rlen) as i64
- }
- });
- if ret == 0 {
- Err(io::standard_error(io::EndOfFile))
- } else if ret < 0 {
- Err(super::last_error())
- } else {
- Ok(ret as uint)
- }
- }
- fn inner_write(&mut self, buf: &[u8]) -> Result<(), IoError> {
- #[cfg(windows)] type wlen = libc::c_uint;
- #[cfg(not(windows))] type wlen = libc::size_t;
- let ret = keep_going(buf, |buf, len| {
- unsafe {
- libc::write(self.fd, buf as *libc::c_void, len as wlen) as i64
- }
- });
- if ret < 0 {
- Err(super::last_error())
- } else {
- Ok(())
- }
- }
-}
-
-impl io::Reader for FileDesc {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- match self.inner_read(buf) { Ok(n) => Some(n), Err(..) => None }
- }
- fn eof(&mut self) -> bool { false }
-}
-
-impl io::Writer for FileDesc {
- fn write(&mut self, buf: &[u8]) {
- self.inner_write(buf);
- }
-}
-
-impl rtio::RtioFileStream for FileDesc {
- fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
- self.inner_read(buf).map(|i| i as int)
- }
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
- self.inner_write(buf)
- }
- fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
- return os_pread(self.fd, vec::raw::to_ptr(buf), buf.len(), offset);
-
- #[cfg(windows)]
- fn os_pread(fd: c_int, buf: *u8, amt: uint, offset: u64) -> IoResult<int> {
- unsafe {
- let mut overlap: libc::OVERLAPPED = intrinsics::init();
- let handle = libc::get_osfhandle(fd) as libc::HANDLE;
- let mut bytes_read = 0;
- overlap.Offset = offset as libc::DWORD;
- overlap.OffsetHigh = (offset >> 32) as libc::DWORD;
-
- match libc::ReadFile(handle, buf as libc::LPVOID,
- amt as libc::DWORD,
- &mut bytes_read, &mut overlap) {
- 0 => Err(super::last_error()),
- _ => Ok(bytes_read as int)
- }
- }
- }
-
- #[cfg(unix)]
- fn os_pread(fd: c_int, buf: *u8, amt: uint, offset: u64) -> IoResult<int> {
- match unsafe {
- libc::pread(fd, buf as *libc::c_void, amt as libc::size_t,
- offset as libc::off_t)
- } {
- -1 => Err(super::last_error()),
- n => Ok(n as int)
- }
- }
- }
- fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
- return os_pwrite(self.fd, vec::raw::to_ptr(buf), buf.len(), offset);
-
- #[cfg(windows)]
- fn os_pwrite(fd: c_int, buf: *u8, amt: uint, offset: u64) -> IoResult<()> {
- unsafe {
- let mut overlap: libc::OVERLAPPED = intrinsics::init();
- let handle = libc::get_osfhandle(fd) as libc::HANDLE;
- overlap.Offset = offset as libc::DWORD;
- overlap.OffsetHigh = (offset >> 32) as libc::DWORD;
-
- match libc::WriteFile(handle, buf as libc::LPVOID,
- amt as libc::DWORD,
- ptr::mut_null(), &mut overlap) {
- 0 => Err(super::last_error()),
- _ => Ok(()),
- }
- }
- }
-
- #[cfg(unix)]
- fn os_pwrite(fd: c_int, buf: *u8, amt: uint, offset: u64) -> IoResult<()> {
- super::mkerr_libc(unsafe {
- libc::pwrite(fd, buf as *libc::c_void, amt as libc::size_t,
- offset as libc::off_t)
- } as c_int)
- }
- }
- #[cfg(windows)]
- fn seek(&mut self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> {
- let whence = match style {
- io::SeekSet => libc::FILE_BEGIN,
- io::SeekEnd => libc::FILE_END,
- io::SeekCur => libc::FILE_CURRENT,
- };
- unsafe {
- let handle = libc::get_osfhandle(self.fd) as libc::HANDLE;
- let mut newpos = 0;
- match libc::SetFilePointerEx(handle, pos, &mut newpos, whence) {
- 0 => Err(super::last_error()),
- _ => Ok(newpos as u64),
- }
- }
- }
- #[cfg(unix)]
- fn seek(&mut self, pos: i64, whence: io::SeekStyle) -> Result<u64, IoError> {
- let whence = match whence {
- io::SeekSet => libc::SEEK_SET,
- io::SeekEnd => libc::SEEK_END,
- io::SeekCur => libc::SEEK_CUR,
- };
- let n = unsafe { libc::lseek(self.fd, pos as libc::off_t, whence) };
- if n < 0 {
- Err(super::last_error())
- } else {
- Ok(n as u64)
- }
- }
- fn tell(&self) -> Result<u64, IoError> {
- let n = unsafe { libc::lseek(self.fd, 0, libc::SEEK_CUR) };
- if n < 0 {
- Err(super::last_error())
- } else {
- Ok(n as u64)
- }
- }
- fn fsync(&mut self) -> Result<(), IoError> {
- return os_fsync(self.fd);
-
- #[cfg(windows)]
- fn os_fsync(fd: c_int) -> IoResult<()> {
- super::mkerr_winbool(unsafe {
- let handle = libc::get_osfhandle(fd);
- libc::FlushFileBuffers(handle as libc::HANDLE)
- })
- }
- #[cfg(unix)]
- fn os_fsync(fd: c_int) -> IoResult<()> {
- super::mkerr_libc(unsafe { libc::fsync(fd) })
- }
- }
- #[cfg(windows)]
- fn datasync(&mut self) -> Result<(), IoError> { return self.fsync(); }
-
- #[cfg(not(windows))]
- fn datasync(&mut self) -> Result<(), IoError> {
- return super::mkerr_libc(os_datasync(self.fd));
-
- #[cfg(target_os = "macos")]
- fn os_datasync(fd: c_int) -> c_int {
- unsafe { libc::fcntl(fd, libc::F_FULLFSYNC) }
- }
- #[cfg(target_os = "linux")]
- fn os_datasync(fd: c_int) -> c_int { unsafe { libc::fdatasync(fd) } }
- #[cfg(not(target_os = "macos"), not(target_os = "linux"))]
- fn os_datasync(fd: c_int) -> c_int { unsafe { libc::fsync(fd) } }
- }
-
- #[cfg(windows)]
- fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
- let orig_pos = match self.tell() { Ok(i) => i, Err(e) => return Err(e) };
- match self.seek(offset, io::SeekSet) {
- Ok(_) => {}, Err(e) => return Err(e),
- };
- let ret = unsafe {
- let handle = libc::get_osfhandle(self.fd) as libc::HANDLE;
- match libc::SetEndOfFile(handle) {
- 0 => Err(super::last_error()),
- _ => Ok(())
- }
- };
- self.seek(orig_pos as i64, io::SeekSet);
- return ret;
- }
- #[cfg(unix)]
- fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
- super::mkerr_libc(unsafe {
- libc::ftruncate(self.fd, offset as libc::off_t)
- })
- }
-}
-
-impl rtio::RtioPipe for FileDesc {
- fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
- self.inner_read(buf)
- }
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
- self.inner_write(buf)
- }
-}
-
-impl rtio::RtioTTY for FileDesc {
- fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
- self.inner_read(buf)
- }
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
- self.inner_write(buf)
- }
- fn set_raw(&mut self, _raw: bool) -> Result<(), IoError> {
- Err(super::unimpl())
- }
- fn get_winsize(&mut self) -> Result<(int, int), IoError> {
- Err(super::unimpl())
- }
- fn isatty(&self) -> bool { false }
-}
-
-impl Drop for FileDesc {
- fn drop(&mut self) {
- // closing stdio file handles makes no sense, so never do it
- if self.close_on_drop && self.fd > libc::STDERR_FILENO {
- unsafe { libc::close(self.fd); }
- }
- }
-}
-
-pub struct CFile {
- priv file: *libc::FILE,
- priv fd: FileDesc,
-}
-
-impl CFile {
- /// Create a `CFile` from an open `FILE` pointer.
- ///
- /// The `CFile` takes ownership of the `FILE` pointer and will close it upon
- /// destruction.
- pub fn new(file: *libc::FILE) -> CFile {
- CFile {
- file: file,
- fd: FileDesc::new(unsafe { libc::fileno(file) }, false)
- }
- }
-
- pub fn flush(&mut self) -> Result<(), IoError> {
- super::mkerr_libc(unsafe { libc::fflush(self.file) })
- }
-}
-
-impl rtio::RtioFileStream for CFile {
- fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
- let ret = keep_going(buf, |buf, len| {
- unsafe {
- libc::fread(buf as *mut libc::c_void, 1, len as libc::size_t,
- self.file) as i64
- }
- });
- if ret == 0 {
- Err(io::standard_error(io::EndOfFile))
- } else if ret < 0 {
- Err(super::last_error())
- } else {
- Ok(ret as int)
- }
- }
-
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
- let ret = keep_going(buf, |buf, len| {
- unsafe {
- libc::fwrite(buf as *libc::c_void, 1, len as libc::size_t,
- self.file) as i64
- }
- });
- if ret < 0 {
- Err(super::last_error())
- } else {
- Ok(())
- }
- }
-
- fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
- self.flush();
- self.fd.pread(buf, offset)
- }
- fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
- self.flush();
- self.fd.pwrite(buf, offset)
- }
- fn seek(&mut self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> {
- let whence = match style {
- io::SeekSet => libc::SEEK_SET,
- io::SeekEnd => libc::SEEK_END,
- io::SeekCur => libc::SEEK_CUR,
- };
- let n = unsafe { libc::fseek(self.file, pos as libc::c_long, whence) };
- if n < 0 {
- Err(super::last_error())
- } else {
- Ok(n as u64)
- }
- }
- fn tell(&self) -> Result<u64, IoError> {
- let ret = unsafe { libc::ftell(self.file) };
- if ret < 0 {
- Err(super::last_error())
- } else {
- Ok(ret as u64)
- }
- }
- fn fsync(&mut self) -> Result<(), IoError> {
- self.flush();
- self.fd.fsync()
- }
- fn datasync(&mut self) -> Result<(), IoError> {
- self.flush();
- self.fd.fsync()
- }
- fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
- self.flush();
- self.fd.truncate(offset)
- }
-}
-
-impl Drop for CFile {
- fn drop(&mut self) {
- unsafe { libc::fclose(self.file); }
- }
-}
-
-pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
- -> IoResult<FileDesc> {
- let flags = match fm {
- io::Open => 0,
- io::Append => libc::O_APPEND,
- io::Truncate => libc::O_TRUNC,
- };
- // Opening with a write permission must silently create the file.
- let (flags, mode) = match fa {
- io::Read => (flags | libc::O_RDONLY, 0),
- io::Write => (flags | libc::O_WRONLY | libc::O_CREAT,
- libc::S_IRUSR | libc::S_IWUSR),
- io::ReadWrite => (flags | libc::O_RDWR | libc::O_CREAT,
- libc::S_IRUSR | libc::S_IWUSR),
- };
-
- return match os_open(path, flags, mode) {
- -1 => Err(super::last_error()),
- fd => Ok(FileDesc::new(fd, true)),
- };
-
- #[cfg(windows)]
- fn os_open(path: &CString, flags: c_int, mode: c_int) -> c_int {
- as_utf16_p(path.as_str().unwrap(), |path| {
- unsafe { libc::wopen(path, flags, mode) }
- })
- }
-
- #[cfg(unix)]
- fn os_open(path: &CString, flags: c_int, mode: c_int) -> c_int {
- unsafe { libc::open(path.with_ref(|p| p), flags, mode) }
- }
-}
-
-pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
- return os_mkdir(p, mode as c_int);
-
- #[cfg(windows)]
- fn os_mkdir(p: &CString, _mode: c_int) -> IoResult<()> {
- super::mkerr_winbool(unsafe {
- // FIXME: turn mode into something useful? #2623
- as_utf16_p(p.as_str().unwrap(), |buf| {
- libc::CreateDirectoryW(buf, ptr::mut_null())
- })
- })
- }
-
- #[cfg(unix)]
- fn os_mkdir(p: &CString, mode: c_int) -> IoResult<()> {
- super::mkerr_libc(unsafe {
- libc::mkdir(p.with_ref(|p| p), mode as libc::mode_t)
- })
- }
-}
-
-pub fn readdir(p: &CString) -> IoResult<~[Path]> {
- fn prune(root: &CString, dirs: ~[Path]) -> ~[Path] {
- let root = unsafe { CString::new(root.with_ref(|p| p), false) };
- let root = Path::new(root);
-
- dirs.move_iter().filter(|path| {
- path.as_vec() != bytes!(".") && path.as_vec() != bytes!("..")
- }).map(|path| root.join(path)).collect()
- }
-
- unsafe {
- #[cfg(not(windows))]
- unsafe fn get_list(p: &CString) -> IoResult<~[Path]> {
- use libc::{dirent_t};
- use libc::{opendir, readdir, closedir};
- extern {
- fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
- }
- debug!("os::list_dir -- BEFORE OPENDIR");
-
- let dir_ptr = p.with_ref(|buf| opendir(buf));
-
- if (dir_ptr as uint != 0) {
- let mut paths = ~[];
- debug!("os::list_dir -- opendir() SUCCESS");
- let mut entry_ptr = readdir(dir_ptr);
- while (entry_ptr as uint != 0) {
- let cstr = CString::new(rust_list_dir_val(entry_ptr), false);
- paths.push(Path::new(cstr));
- entry_ptr = readdir(dir_ptr);
- }
- closedir(dir_ptr);
- Ok(paths)
- } else {
- Err(super::last_error())
- }
- }
-
- #[cfg(windows)]
- unsafe fn get_list(p: &CString) -> IoResult<~[Path]> {
- use libc::consts::os::extra::INVALID_HANDLE_VALUE;
- use libc::{wcslen, free};
- use libc::funcs::extra::kernel32::{
- FindFirstFileW,
- FindNextFileW,
- FindClose,
- };
- use libc::types::os::arch::extra::HANDLE;
- use os::win32::{
- as_utf16_p
- };
- use rt::global_heap::malloc_raw;
-
- #[nolink]
- extern {
- fn rust_list_dir_wfd_size() -> libc::size_t;
- fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void) -> *u16;
- }
- let p = CString::new(p.with_ref(|p| p), false);
- let p = Path::new(p);
- let star = p.join("*");
- as_utf16_p(star.as_str().unwrap(), |path_ptr| {
- let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
- let find_handle = FindFirstFileW(path_ptr, wfd_ptr as HANDLE);
- if find_handle as libc::c_int != INVALID_HANDLE_VALUE {
- let mut paths = ~[];
- let mut more_files = 1 as libc::c_int;
- while more_files != 0 {
- let fp_buf = rust_list_dir_wfd_fp_buf(wfd_ptr);
- if fp_buf as uint == 0 {
- fail!("os::list_dir() failure: got null ptr from wfd");
- }
- else {
- let fp_vec = vec::from_buf(
- fp_buf, wcslen(fp_buf) as uint);
- let fp_str = str::from_utf16(fp_vec);
- paths.push(Path::new(fp_str));
- }
- more_files = FindNextFileW(find_handle, wfd_ptr as HANDLE);
- }
- FindClose(find_handle);
- free(wfd_ptr);
- Ok(paths)
- } else {
- Err(super::last_error())
- }
- })
- }
-
- get_list(p).map(|paths| prune(p, paths))
- }
-}
-
-pub fn unlink(p: &CString) -> IoResult<()> {
- return os_unlink(p);
-
- #[cfg(windows)]
- fn os_unlink(p: &CString) -> IoResult<()> {
- super::mkerr_winbool(unsafe {
- as_utf16_p(p.as_str().unwrap(), |buf| {
- libc::DeleteFileW(buf)
- })
- })
- }
-
- #[cfg(unix)]
- fn os_unlink(p: &CString) -> IoResult<()> {
- super::mkerr_libc(unsafe { libc::unlink(p.with_ref(|p| p)) })
- }
-}
-
-pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
- return os_rename(old, new);
-
- #[cfg(windows)]
- fn os_rename(old: &CString, new: &CString) -> IoResult<()> {
- super::mkerr_winbool(unsafe {
- as_utf16_p(old.as_str().unwrap(), |old| {
- as_utf16_p(new.as_str().unwrap(), |new| {
- libc::MoveFileExW(old, new, libc::MOVEFILE_REPLACE_EXISTING)
- })
- })
- })
- }
-
- #[cfg(unix)]
- fn os_rename(old: &CString, new: &CString) -> IoResult<()> {
- super::mkerr_libc(unsafe {
- libc::rename(old.with_ref(|p| p), new.with_ref(|p| p))
- })
- }
-}
-
-pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
- return super::mkerr_libc(os_chmod(p, mode as c_int));
-
- #[cfg(windows)]
- fn os_chmod(p: &CString, mode: c_int) -> c_int {
- unsafe {
- as_utf16_p(p.as_str().unwrap(), |p| libc::wchmod(p, mode))
- }
- }
-
- #[cfg(unix)]
- fn os_chmod(p: &CString, mode: c_int) -> c_int {
- unsafe { libc::chmod(p.with_ref(|p| p), mode as libc::mode_t) }
- }
-}
-
-pub fn rmdir(p: &CString) -> IoResult<()> {
- return super::mkerr_libc(os_rmdir(p));
-
- #[cfg(windows)]
- fn os_rmdir(p: &CString) -> c_int {
- unsafe {
- as_utf16_p(p.as_str().unwrap(), |p| libc::wrmdir(p))
- }
- }
-
- #[cfg(unix)]
- fn os_rmdir(p: &CString) -> c_int {
- unsafe { libc::rmdir(p.with_ref(|p| p)) }
- }
-}
-
-pub fn chown(p: &CString, uid: int, gid: int) -> IoResult<()> {
- return super::mkerr_libc(os_chown(p, uid, gid));
-
- // libuv has this as a no-op, so seems like this should as well?
- #[cfg(windows)]
- fn os_chown(_p: &CString, _uid: int, _gid: int) -> c_int { 0 }
-
- #[cfg(unix)]
- fn os_chown(p: &CString, uid: int, gid: int) -> c_int {
- unsafe {
- libc::chown(p.with_ref(|p| p), uid as libc::uid_t,
- gid as libc::gid_t)
- }
- }
-}
-
-pub fn readlink(p: &CString) -> IoResult<Path> {
- return os_readlink(p);
-
- // XXX: I have a feeling that this reads intermediate symlinks as well.
- #[cfg(windows)]
- fn os_readlink(p: &CString) -> IoResult<Path> {
- let handle = unsafe {
- as_utf16_p(p.as_str().unwrap(), |p| {
- libc::CreateFileW(p,
- libc::GENERIC_READ,
- libc::FILE_SHARE_READ,
- ptr::mut_null(),
- libc::OPEN_EXISTING,
- libc::FILE_ATTRIBUTE_NORMAL,
- ptr::mut_null())
- })
- };
- if handle == ptr::mut_null() { return Err(super::last_error()) }
- let ret = fill_utf16_buf_and_decode(|buf, sz| {
- unsafe {
- libc::GetFinalPathNameByHandleW(handle, buf as *u16, sz,
- libc::VOLUME_NAME_NT)
- }
- });
- let ret = match ret {
- Some(s) => Ok(Path::new(s)),
- None => Err(super::last_error()),
- };
- unsafe { libc::CloseHandle(handle) };
- return ret;
-
- }
-
- #[cfg(unix)]
- fn os_readlink(p: &CString) -> IoResult<Path> {
- let p = p.with_ref(|p| p);
- let mut len = unsafe { libc::pathconf(p, libc::_PC_NAME_MAX) };
- if len == -1 {
- len = 1024; // XXX: read PATH_MAX from C ffi?
- }
- let mut buf = vec::with_capacity::<u8>(len as uint);
- match unsafe {
- libc::readlink(p, vec::raw::to_ptr(buf) as *mut libc::c_char,
- len as libc::size_t)
- } {
- -1 => Err(super::last_error()),
- n => {
- assert!(n > 0);
- unsafe { vec::raw::set_len(&mut buf, n as uint); }
- Ok(Path::new(buf))
- }
- }
- }
-}
-
-pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
- return os_symlink(src, dst);
-
- #[cfg(windows)]
- fn os_symlink(src: &CString, dst: &CString) -> IoResult<()> {
- super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
- as_utf16_p(dst.as_str().unwrap(), |dst| {
- unsafe { libc::CreateSymbolicLinkW(dst, src, 0) }
- })
- }))
- }
-
- #[cfg(unix)]
- fn os_symlink(src: &CString, dst: &CString) -> IoResult<()> {
- super::mkerr_libc(unsafe {
- libc::symlink(src.with_ref(|p| p), dst.with_ref(|p| p))
- })
- }
-}
-
-pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
- return os_link(src, dst);
-
- #[cfg(windows)]
- fn os_link(src: &CString, dst: &CString) -> IoResult<()> {
- super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
- as_utf16_p(dst.as_str().unwrap(), |dst| {
- unsafe { libc::CreateHardLinkW(dst, src, ptr::mut_null()) }
- })
- }))
- }
-
- #[cfg(unix)]
- fn os_link(src: &CString, dst: &CString) -> IoResult<()> {
- super::mkerr_libc(unsafe {
- libc::link(src.with_ref(|p| p), dst.with_ref(|p| p))
- })
- }
-}
-
-#[cfg(windows)]
-fn mkstat(stat: &libc::stat, path: &CString) -> io::FileStat {
- let path = unsafe { CString::new(path.with_ref(|p| p), false) };
-
- // FileStat times are in milliseconds
- fn mktime(secs: u64, nsecs: u64) -> u64 { secs * 1000 + nsecs / 1000000 }
-
- let kind = match (stat.st_mode as c_int) & libc::S_IFMT {
- libc::S_IFREG => io::TypeFile,
- libc::S_IFDIR => io::TypeDirectory,
- libc::S_IFIFO => io::TypeNamedPipe,
- libc::S_IFBLK => io::TypeBlockSpecial,
- libc::S_IFLNK => io::TypeSymlink,
- _ => io::TypeUnknown,
- };
-
- io::FileStat {
- path: Path::new(path),
- size: stat.st_size as u64,
- kind: kind,
- perm: (stat.st_mode) as io::FilePermission & io::AllPermissions,
- created: stat.st_ctime as u64,
- modified: stat.st_mtime as u64,
- accessed: stat.st_atime as u64,
- unstable: io::UnstableFileStat {
- device: stat.st_dev as u64,
- inode: stat.st_ino as u64,
- rdev: stat.st_rdev as u64,
- nlink: stat.st_nlink as u64,
- uid: stat.st_uid as u64,
- gid: stat.st_gid as u64,
- blksize: 0,
- blocks: 0,
- flags: 0,
- gen: 0,
- }
- }
-}
-
-#[cfg(unix)]
-fn mkstat(stat: &libc::stat, path: &CString) -> io::FileStat {
- let path = unsafe { CString::new(path.with_ref(|p| p), false) };
-
- // FileStat times are in milliseconds
- fn mktime(secs: u64, nsecs: u64) -> u64 { secs * 1000 + nsecs / 1000000 }
-
- let kind = match (stat.st_mode as c_int) & libc::S_IFMT {
- libc::S_IFREG => io::TypeFile,
- libc::S_IFDIR => io::TypeDirectory,
- libc::S_IFIFO => io::TypeNamedPipe,
- libc::S_IFBLK => io::TypeBlockSpecial,
- libc::S_IFLNK => io::TypeSymlink,
- _ => io::TypeUnknown,
- };
-
- #[cfg(not(target_os = "linux"), not(target_os = "android"))]
- fn flags(stat: &libc::stat) -> u64 { stat.st_flags as u64 }
- #[cfg(target_os = "linux")] #[cfg(target_os = "android")]
- fn flags(_stat: &libc::stat) -> u64 { 0 }
-
- #[cfg(not(target_os = "linux"), not(target_os = "android"))]
- fn gen(stat: &libc::stat) -> u64 { stat.st_gen as u64 }
- #[cfg(target_os = "linux")] #[cfg(target_os = "android")]
- fn gen(_stat: &libc::stat) -> u64 { 0 }
-
- io::FileStat {
- path: Path::new(path),
- size: stat.st_size as u64,
- kind: kind,
- perm: (stat.st_mode) as io::FilePermission & io::AllPermissions,
- created: mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64),
- modified: mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64),
- accessed: mktime(stat.st_atime as u64, stat.st_atime_nsec as u64),
- unstable: io::UnstableFileStat {
- device: stat.st_dev as u64,
- inode: stat.st_ino as u64,
- rdev: stat.st_rdev as u64,
- nlink: stat.st_nlink as u64,
- uid: stat.st_uid as u64,
- gid: stat.st_gid as u64,
- blksize: stat.st_blksize as u64,
- blocks: stat.st_blocks as u64,
- flags: flags(stat),
- gen: gen(stat),
- }
- }
-}
-
-pub fn stat(p: &CString) -> IoResult<io::FileStat> {
- return os_stat(p);
-
- #[cfg(windows)]
- fn os_stat(p: &CString) -> IoResult<io::FileStat> {
- let mut stat: libc::stat = unsafe { intrinsics::uninit() };
- as_utf16_p(p.as_str().unwrap(), |up| {
- match unsafe { libc::wstat(up, &mut stat) } {
- 0 => Ok(mkstat(&stat, p)),
- _ => Err(super::last_error()),
- }
- })
- }
-
- #[cfg(unix)]
- fn os_stat(p: &CString) -> IoResult<io::FileStat> {
- let mut stat: libc::stat = unsafe { intrinsics::uninit() };
- match unsafe { libc::stat(p.with_ref(|p| p), &mut stat) } {
- 0 => Ok(mkstat(&stat, p)),
- _ => Err(super::last_error()),
- }
- }
-}
-
-pub fn lstat(p: &CString) -> IoResult<io::FileStat> {
- return os_lstat(p);
-
- // XXX: windows implementation is missing
- #[cfg(windows)]
- fn os_lstat(_p: &CString) -> IoResult<io::FileStat> {
- Err(super::unimpl())
- }
-
- #[cfg(unix)]
- fn os_lstat(p: &CString) -> IoResult<io::FileStat> {
- let mut stat: libc::stat = unsafe { intrinsics::uninit() };
- match unsafe { libc::lstat(p.with_ref(|p| p), &mut stat) } {
- 0 => Ok(mkstat(&stat, p)),
- _ => Err(super::last_error()),
- }
- }
-}
-
-pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
- return super::mkerr_libc(os_utime(p, atime, mtime));
-
- #[cfg(windows)]
- fn os_utime(p: &CString, atime: u64, mtime: u64) -> c_int {
- let buf = libc::utimbuf {
- actime: (atime / 1000) as libc::time64_t,
- modtime: (mtime / 1000) as libc::time64_t,
- };
- unsafe {
- as_utf16_p(p.as_str().unwrap(), |p| libc::wutime(p, &buf))
- }
- }
-
- #[cfg(unix)]
- fn os_utime(p: &CString, atime: u64, mtime: u64) -> c_int {
- let buf = libc::utimbuf {
- actime: (atime / 1000) as libc::time_t,
- modtime: (mtime / 1000) as libc::time_t,
- };
- unsafe { libc::utime(p.with_ref(|p| p), &buf) }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use io::native::file::{CFile, FileDesc};
- use io::fs;
- use io;
- use libc;
- use os;
- use path::Path;
- use rand;
- use result::Ok;
- use rt::rtio::RtioFileStream;
-
- fn tmpdir() -> Path {
- let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
- fs::mkdir(&ret, io::UserRWX);
- ret
- }
-
- #[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
- fn test_file_desc() {
- // Run this test with some pipes so we don't have to mess around with
- // opening or closing files.
- unsafe {
- let os::Pipe { input, out } = os::pipe();
- let mut reader = FileDesc::new(input, true);
- let mut writer = FileDesc::new(out, true);
-
- writer.inner_write(bytes!("test"));
- let mut buf = [0u8, ..4];
- match reader.inner_read(buf) {
- Ok(4) => {
- assert_eq!(buf[0], 't' as u8);
- assert_eq!(buf[1], 'e' as u8);
- assert_eq!(buf[2], 's' as u8);
- assert_eq!(buf[3], 't' as u8);
- }
- r => fail!("invalid read: {:?}", r)
- }
-
- assert!(writer.inner_read(buf).is_err());
- assert!(reader.inner_write(buf).is_err());
- }
- }
-
- #[ignore(cfg(windows))] // apparently windows doesn't like tmpfile
- fn test_cfile() {
- unsafe {
- let f = libc::tmpfile();
- assert!(!f.is_null());
- let mut file = CFile::new(f);
-
- file.write(bytes!("test"));
- let mut buf = [0u8, ..4];
- file.seek(0, io::SeekSet);
- match file.read(buf) {
- Ok(4) => {
- assert_eq!(buf[0], 't' as u8);
- assert_eq!(buf[1], 'e' as u8);
- assert_eq!(buf[2], 's' as u8);
- assert_eq!(buf[3], 't' as u8);
- }
- r => fail!("invalid read: {:?}", r)
- }
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Native thread-blocking I/O implementation
-//!
-//! This module contains the implementation of native thread-blocking
-//! implementations of I/O on all platforms. This module is not intended to be
-//! used directly, but rather the rust runtime will fall back to using it if
-//! necessary.
-//!
-//! Rust code normally runs inside of green tasks with a local scheduler using
-//! asynchronous I/O to cooperate among tasks. This model is not always
-//! available, however, and that's where these native implementations come into
-//! play. The only dependencies of these modules are the normal system libraries
-//! that you would find on the respective platform.
-
-use c_str::CString;
-use comm::SharedChan;
-use libc::c_int;
-use libc;
-use option::{Option, None, Some};
-use os;
-use path::Path;
-use result::{Result, Ok, Err};
-use rt::rtio;
-use rt::rtio::{RtioTcpStream, RtioTcpListener, RtioUdpSocket, RtioUnixListener,
- RtioPipe, RtioFileStream, RtioProcess, RtioSignal, RtioTTY,
- CloseBehavior, RtioTimer};
-use io;
-use io::IoError;
-use io::net::ip::SocketAddr;
-use io::process::ProcessConfig;
-use io::signal::Signum;
-use ai = io::net::addrinfo;
-
-// Local re-exports
-pub use self::file::FileDesc;
-pub use self::process::Process;
-
-// Native I/O implementations
-pub mod file;
-pub mod process;
-
-type IoResult<T> = Result<T, IoError>;
-
-fn unimpl() -> IoError {
- IoError {
- kind: io::IoUnavailable,
- desc: "unimplemented I/O interface",
- detail: None,
- }
-}
-
-fn last_error() -> IoError {
- #[cfg(windows)]
- fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
- match errno {
- libc::EOF => (io::EndOfFile, "end of file"),
- _ => (io::OtherIoError, "unknown error"),
- }
- }
-
- #[cfg(not(windows))]
- fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
- // XXX: this should probably be a bit more descriptive...
- match errno {
- libc::EOF => (io::EndOfFile, "end of file"),
-
- // These two constants can have the same value on some systems, but
- // different values on others, so we can't use a match clause
- x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
- (io::ResourceUnavailable, "resource temporarily unavailable"),
-
- _ => (io::OtherIoError, "unknown error"),
- }
- }
-
- let (kind, desc) = get_err(os::errno() as i32);
- IoError {
- kind: kind,
- desc: desc,
- detail: Some(os::last_os_error())
- }
-}
-
-// unix has nonzero values as errors
-fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
- if ret != 0 {
- Err(last_error())
- } else {
- Ok(())
- }
-}
-
-// windows has zero values as errors
-fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
- if ret == 0 {
- Err(last_error())
- } else {
- Ok(())
- }
-}
-
-/// Implementation of rt::rtio's IoFactory trait to generate handles to the
-/// native I/O functionality.
-pub struct IoFactory;
-
-impl rtio::IoFactory for IoFactory {
- // networking
- fn tcp_connect(&mut self, _addr: SocketAddr) -> IoResult<~RtioTcpStream> {
- Err(unimpl())
- }
- fn tcp_bind(&mut self, _addr: SocketAddr) -> IoResult<~RtioTcpListener> {
- Err(unimpl())
- }
- fn udp_bind(&mut self, _addr: SocketAddr) -> IoResult<~RtioUdpSocket> {
- Err(unimpl())
- }
- fn unix_bind(&mut self, _path: &CString) -> IoResult<~RtioUnixListener> {
- Err(unimpl())
- }
- fn unix_connect(&mut self, _path: &CString) -> IoResult<~RtioPipe> {
- Err(unimpl())
- }
- fn get_host_addresses(&mut self, _host: Option<&str>, _servname: Option<&str>,
- _hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
- Err(unimpl())
- }
-
- // filesystem operations
- fn fs_from_raw_fd(&mut self, fd: c_int,
- close: CloseBehavior) -> ~RtioFileStream {
- let close = match close {
- rtio::CloseSynchronously | rtio::CloseAsynchronously => true,
- rtio::DontClose => false
- };
- ~file::FileDesc::new(fd, close) as ~RtioFileStream
- }
- fn fs_open(&mut self, path: &CString, fm: io::FileMode, fa: io::FileAccess)
- -> IoResult<~RtioFileStream> {
- file::open(path, fm, fa).map(|fd| ~fd as ~RtioFileStream)
- }
- fn fs_unlink(&mut self, path: &CString) -> IoResult<()> {
- file::unlink(path)
- }
- fn fs_stat(&mut self, path: &CString) -> IoResult<io::FileStat> {
- file::stat(path)
- }
- fn fs_mkdir(&mut self, path: &CString,
- mode: io::FilePermission) -> IoResult<()> {
- file::mkdir(path, mode)
- }
- fn fs_chmod(&mut self, path: &CString,
- mode: io::FilePermission) -> IoResult<()> {
- file::chmod(path, mode)
- }
- fn fs_rmdir(&mut self, path: &CString) -> IoResult<()> {
- file::rmdir(path)
- }
- fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()> {
- file::rename(path, to)
- }
- fn fs_readdir(&mut self, path: &CString, _flags: c_int) -> IoResult<~[Path]> {
- file::readdir(path)
- }
- fn fs_lstat(&mut self, path: &CString) -> IoResult<io::FileStat> {
- file::lstat(path)
- }
- fn fs_chown(&mut self, path: &CString, uid: int, gid: int) -> IoResult<()> {
- file::chown(path, uid, gid)
- }
- fn fs_readlink(&mut self, path: &CString) -> IoResult<Path> {
- file::readlink(path)
- }
- fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()> {
- file::symlink(src, dst)
- }
- fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()> {
- file::link(src, dst)
- }
- fn fs_utime(&mut self, src: &CString, atime: u64,
- mtime: u64) -> IoResult<()> {
- file::utime(src, atime, mtime)
- }
-
- // misc
- fn timer_init(&mut self) -> IoResult<~RtioTimer> {
- Err(unimpl())
- }
- fn spawn(&mut self, config: ProcessConfig)
- -> IoResult<(~RtioProcess, ~[Option<~RtioPipe>])> {
- process::Process::spawn(config).map(|(p, io)| {
- (~p as ~RtioProcess,
- io.move_iter().map(|p| p.map(|p| ~p as ~RtioPipe)).collect())
- })
- }
- fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe> {
- Ok(~file::FileDesc::new(fd, true) as ~RtioPipe)
- }
- fn tty_open(&mut self, fd: c_int, _readable: bool) -> IoResult<~RtioTTY> {
- if unsafe { libc::isatty(fd) } != 0 {
- Ok(~file::FileDesc::new(fd, true) as ~RtioTTY)
- } else {
- Err(IoError {
- kind: io::MismatchedFileTypeForOperation,
- desc: "file descriptor is not a TTY",
- detail: None,
- })
- }
- }
- fn signal(&mut self, _signal: Signum, _channel: SharedChan<Signum>)
- -> IoResult<~RtioSignal> {
- Err(unimpl())
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cast;
-use io;
-use libc::{pid_t, c_void, c_int};
-use libc;
-use os;
-use prelude::*;
-use ptr;
-use rt::rtio;
-use super::file;
-
-use p = io::process;
-
-/**
- * A value representing a child process.
- *
- * The lifetime of this value is linked to the lifetime of the actual
- * process - the Process destructor calls self.finish() which waits
- * for the process to terminate.
- */
-pub struct Process {
- /// The unique id of the process (this should never be negative).
- priv pid: pid_t,
-
- /// A handle to the process - on unix this will always be NULL, but on
- /// windows it will be a HANDLE to the process, which will prevent the
- /// pid being re-used until the handle is closed.
- priv handle: *(),
-
- /// None until finish() is called.
- priv exit_code: Option<int>,
-}
-
-impl Process {
- /// Creates a new process using native process-spawning abilities provided
- /// by the OS. Operations on this process will be blocking instead of using
- /// the runtime for sleeping just this current task.
- ///
- /// # Arguments
- ///
- /// * prog - the program to run
- /// * args - the arguments to pass to the program, not including the program
- /// itself
- /// * env - an optional envrionment to specify for the child process. If
- /// this value is `None`, then the child will inherit the parent's
- /// environment
- /// * cwd - an optionally specified current working directory of the child,
- /// defaulting to the parent's current working directory
- /// * stdin, stdout, stderr - These optionally specified file descriptors
- /// dictate where the stdin/out/err of the child process will go. If
- /// these are `None`, then this module will bind the input/output to an
- /// os pipe instead. This process takes ownership of these file
- /// descriptors, closing them upon destruction of the process.
- pub fn spawn(config: p::ProcessConfig)
- -> Result<(Process, ~[Option<file::FileDesc>]), io::IoError>
- {
- // right now we only handle stdin/stdout/stderr.
- if config.io.len() > 3 {
- return Err(super::unimpl());
- }
-
- fn get_io(io: &[p::StdioContainer],
- ret: &mut ~[Option<file::FileDesc>],
- idx: uint) -> (Option<os::Pipe>, c_int) {
- if idx >= io.len() { return (None, -1); }
- ret.push(None);
- match io[idx] {
- p::Ignored => (None, -1),
- p::InheritFd(fd) => (None, fd),
- p::CreatePipe(readable, _writable) => {
- let pipe = os::pipe();
- let (theirs, ours) = if readable {
- (pipe.input, pipe.out)
- } else {
- (pipe.out, pipe.input)
- };
- ret[idx] = Some(file::FileDesc::new(ours, true));
- (Some(pipe), theirs)
- }
- }
- }
-
- let mut ret_io = ~[];
- let (in_pipe, in_fd) = get_io(config.io, &mut ret_io, 0);
- let (out_pipe, out_fd) = get_io(config.io, &mut ret_io, 1);
- let (err_pipe, err_fd) = get_io(config.io, &mut ret_io, 2);
-
- let env = config.env.map(|a| a.to_owned());
- let cwd = config.cwd.map(|a| Path::new(a));
- let res = spawn_process_os(config.program, config.args, env,
- cwd.as_ref(), in_fd, out_fd, err_fd);
-
- unsafe {
- for pipe in in_pipe.iter() { libc::close(pipe.input); }
- for pipe in out_pipe.iter() { libc::close(pipe.out); }
- for pipe in err_pipe.iter() { libc::close(pipe.out); }
- }
-
- Ok((Process { pid: res.pid, handle: res.handle, exit_code: None }, ret_io))
- }
-}
-
-impl rtio::RtioProcess for Process {
- fn id(&self) -> pid_t { self.pid }
-
- fn wait(&mut self) -> p::ProcessExit {
- let code = match self.exit_code {
- Some(code) => code,
- None => {
- let code = waitpid(self.pid);
- self.exit_code = Some(code);
- code
- }
- };
- return p::ExitStatus(code); // XXX: this is wrong
- }
-
- fn kill(&mut self, signum: int) -> Result<(), io::IoError> {
- // if the process has finished, and therefore had waitpid called,
- // and we kill it, then on unix we might ending up killing a
- // newer process that happens to have the same (re-used) id
- match self.exit_code {
- Some(..) => return Err(io::IoError {
- kind: io::OtherIoError,
- desc: "can't kill an exited process",
- detail: None,
- }),
- None => {}
- }
- return unsafe { killpid(self.pid, signum) };
-
- #[cfg(windows)]
- unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
- match signal {
- io::process::PleaseExitSignal | io::process::MustDieSignal => {
- libc::funcs::extra::kernel32::TerminateProcess(
- cast::transmute(pid), 1);
- Ok(())
- }
- _ => Err(io::IoError {
- kind: io::OtherIoError,
- desc: "unsupported signal on windows",
- detail: None,
- })
- }
- }
-
- #[cfg(not(windows))]
- unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
- libc::funcs::posix88::signal::kill(pid, signal as c_int);
- Ok(())
- }
- }
-}
-
-impl Drop for Process {
- fn drop(&mut self) {
- free_handle(self.handle);
- }
-}
-
-struct SpawnProcessResult {
- pid: pid_t,
- handle: *(),
-}
-
-#[cfg(windows)]
-fn spawn_process_os(prog: &str, args: &[~str],
- env: Option<~[(~str, ~str)]>,
- dir: Option<&Path>,
- in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
- use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
- use libc::consts::os::extra::{
- TRUE, FALSE,
- STARTF_USESTDHANDLES,
- INVALID_HANDLE_VALUE,
- DUPLICATE_SAME_ACCESS
- };
- use libc::funcs::extra::kernel32::{
- GetCurrentProcess,
- DuplicateHandle,
- CloseHandle,
- CreateProcessA
- };
- use libc::funcs::extra::msvcrt::get_osfhandle;
-
- use mem;
-
- unsafe {
-
- let mut si = zeroed_startupinfo();
- si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
- si.dwFlags = STARTF_USESTDHANDLES;
-
- let cur_proc = GetCurrentProcess();
-
- let orig_std_in = get_osfhandle(in_fd) as HANDLE;
- if orig_std_in == INVALID_HANDLE_VALUE as HANDLE {
- fail!("failure in get_osfhandle: {}", os::last_os_error());
- }
- if DuplicateHandle(cur_proc, orig_std_in, cur_proc, &mut si.hStdInput,
- 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE {
- fail!("failure in DuplicateHandle: {}", os::last_os_error());
- }
-
- let orig_std_out = get_osfhandle(out_fd) as HANDLE;
- if orig_std_out == INVALID_HANDLE_VALUE as HANDLE {
- fail!("failure in get_osfhandle: {}", os::last_os_error());
- }
- if DuplicateHandle(cur_proc, orig_std_out, cur_proc, &mut si.hStdOutput,
- 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE {
- fail!("failure in DuplicateHandle: {}", os::last_os_error());
- }
-
- let orig_std_err = get_osfhandle(err_fd) as HANDLE;
- if orig_std_err == INVALID_HANDLE_VALUE as HANDLE {
- fail!("failure in get_osfhandle: {}", os::last_os_error());
- }
- if DuplicateHandle(cur_proc, orig_std_err, cur_proc, &mut si.hStdError,
- 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE {
- fail!("failure in DuplicateHandle: {}", os::last_os_error());
- }
-
- let cmd = make_command_line(prog, args);
- let mut pi = zeroed_process_information();
- let mut create_err = None;
-
- with_envp(env, |envp| {
- with_dirp(dir, |dirp| {
- cmd.with_c_str(|cmdp| {
- let created = CreateProcessA(ptr::null(), cast::transmute(cmdp),
- ptr::mut_null(), ptr::mut_null(), TRUE,
- 0, envp, dirp, &mut si, &mut pi);
- if created == FALSE {
- create_err = Some(os::last_os_error());
- }
- })
- })
- });
-
- CloseHandle(si.hStdInput);
- CloseHandle(si.hStdOutput);
- CloseHandle(si.hStdError);
-
- for msg in create_err.iter() {
- fail!("failure in CreateProcess: {}", *msg);
- }
-
- // We close the thread handle because we don't care about keeping the
- // thread id valid, and we aren't keeping the thread handle around to be
- // able to close it later. We don't close the process handle however
- // because we want the process id to stay valid at least until the
- // calling code closes the process handle.
- CloseHandle(pi.hThread);
-
- SpawnProcessResult {
- pid: pi.dwProcessId as pid_t,
- handle: pi.hProcess as *()
- }
- }
-}
-
-#[cfg(windows)]
-fn zeroed_startupinfo() -> libc::types::os::arch::extra::STARTUPINFO {
- libc::types::os::arch::extra::STARTUPINFO {
- cb: 0,
- lpReserved: ptr::mut_null(),
- lpDesktop: ptr::mut_null(),
- lpTitle: ptr::mut_null(),
- dwX: 0,
- dwY: 0,
- dwXSize: 0,
- dwYSize: 0,
- dwXCountChars: 0,
- dwYCountCharts: 0,
- dwFillAttribute: 0,
- dwFlags: 0,
- wShowWindow: 0,
- cbReserved2: 0,
- lpReserved2: ptr::mut_null(),
- hStdInput: ptr::mut_null(),
- hStdOutput: ptr::mut_null(),
- hStdError: ptr::mut_null()
- }
-}
-
-#[cfg(windows)]
-fn zeroed_process_information() -> libc::types::os::arch::extra::PROCESS_INFORMATION {
- libc::types::os::arch::extra::PROCESS_INFORMATION {
- hProcess: ptr::mut_null(),
- hThread: ptr::mut_null(),
- dwProcessId: 0,
- dwThreadId: 0
- }
-}
-
-// FIXME: this is only pub so it can be tested (see issue #4536)
-#[cfg(windows)]
-pub fn make_command_line(prog: &str, args: &[~str]) -> ~str {
- let mut cmd = ~"";
- append_arg(&mut cmd, prog);
- for arg in args.iter() {
- cmd.push_char(' ');
- append_arg(&mut cmd, *arg);
- }
- return cmd;
-
- fn append_arg(cmd: &mut ~str, arg: &str) {
- let quote = arg.chars().any(|c| c == ' ' || c == '\t');
- if quote {
- cmd.push_char('"');
- }
- for i in range(0u, arg.len()) {
- append_char_at(cmd, arg, i);
- }
- if quote {
- cmd.push_char('"');
- }
- }
-
- fn append_char_at(cmd: &mut ~str, arg: &str, i: uint) {
- match arg[i] as char {
- '"' => {
- // Escape quotes.
- cmd.push_str("\\\"");
- }
- '\\' => {
- if backslash_run_ends_in_quote(arg, i) {
- // Double all backslashes that are in runs before quotes.
- cmd.push_str("\\\\");
- } else {
- // Pass other backslashes through unescaped.
- cmd.push_char('\\');
- }
- }
- c => {
- cmd.push_char(c);
- }
- }
- }
-
- fn backslash_run_ends_in_quote(s: &str, mut i: uint) -> bool {
- while i < s.len() && s[i] as char == '\\' {
- i += 1;
- }
- return i < s.len() && s[i] as char == '"';
- }
-}
-
-#[cfg(unix)]
-fn spawn_process_os(prog: &str, args: &[~str],
- env: Option<~[(~str, ~str)]>,
- dir: Option<&Path>,
- in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
- use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
- use libc::funcs::bsd44::getdtablesize;
-
- mod rustrt {
- extern {
- pub fn rust_unset_sigprocmask();
- }
- }
-
- #[cfg(windows)]
- unsafe fn set_environ(_envp: *c_void) {}
- #[cfg(target_os = "macos")]
- unsafe fn set_environ(envp: *c_void) {
- extern { fn _NSGetEnviron() -> *mut *c_void; }
-
- *_NSGetEnviron() = envp;
- }
- #[cfg(not(target_os = "macos"), not(windows))]
- unsafe fn set_environ(envp: *c_void) {
- extern {
- static mut environ: *c_void;
- }
- environ = envp;
- }
-
- unsafe {
-
- let pid = fork();
- if pid < 0 {
- fail!("failure in fork: {}", os::last_os_error());
- } else if pid > 0 {
- return SpawnProcessResult {pid: pid, handle: ptr::null()};
- }
-
- rustrt::rust_unset_sigprocmask();
-
- if dup2(in_fd, 0) == -1 {
- fail!("failure in dup2(in_fd, 0): {}", os::last_os_error());
- }
- if dup2(out_fd, 1) == -1 {
- fail!("failure in dup2(out_fd, 1): {}", os::last_os_error());
- }
- if dup2(err_fd, 2) == -1 {
- fail!("failure in dup3(err_fd, 2): {}", os::last_os_error());
- }
- // close all other fds
- for fd in range(3, getdtablesize()).invert() {
- close(fd as c_int);
- }
-
- with_dirp(dir, |dirp| {
- if !dirp.is_null() && chdir(dirp) == -1 {
- fail!("failure in chdir: {}", os::last_os_error());
- }
- });
-
- with_envp(env, |envp| {
- if !envp.is_null() {
- set_environ(envp);
- }
- with_argv(prog, args, |argv| {
- execvp(*argv, argv);
- // execvp only returns if an error occurred
- fail!("failure in execvp: {}", os::last_os_error());
- })
- })
- }
-}
-
-#[cfg(unix)]
-fn with_argv<T>(prog: &str, args: &[~str], cb: |**libc::c_char| -> T) -> T {
- use vec;
-
- // We can't directly convert `str`s into `*char`s, as someone needs to hold
- // a reference to the intermediary byte buffers. So first build an array to
- // hold all the ~[u8] byte strings.
- let mut tmps = vec::with_capacity(args.len() + 1);
-
- tmps.push(prog.to_c_str());
-
- for arg in args.iter() {
- tmps.push(arg.to_c_str());
- }
-
- // Next, convert each of the byte strings into a pointer. This is
- // technically unsafe as the caller could leak these pointers out of our
- // scope.
- let mut ptrs = tmps.map(|tmp| tmp.with_ref(|buf| buf));
-
- // Finally, make sure we add a null pointer.
- ptrs.push(ptr::null());
-
- ptrs.as_imm_buf(|buf, _| cb(buf))
-}
-
-#[cfg(unix)]
-fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*c_void| -> T) -> T {
- use vec;
-
- // On posixy systems we can pass a char** for envp, which is a
- // null-terminated array of "k=v\n" strings. Like `with_argv`, we have to
- // have a temporary buffer to hold the intermediary `~[u8]` byte strings.
- match env {
- Some(env) => {
- let mut tmps = vec::with_capacity(env.len());
-
- for pair in env.iter() {
- let kv = format!("{}={}", pair.first(), pair.second());
- tmps.push(kv.to_c_str());
- }
-
- // Once again, this is unsafe.
- let mut ptrs = tmps.map(|tmp| tmp.with_ref(|buf| buf));
- ptrs.push(ptr::null());
-
- ptrs.as_imm_buf(|buf, _| unsafe { cb(cast::transmute(buf)) })
- }
- _ => cb(ptr::null())
- }
-}
-
-#[cfg(windows)]
-fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*mut c_void| -> T) -> T {
- // On win32 we pass an "environment block" which is not a char**, but
- // rather a concatenation of null-terminated k=v\0 sequences, with a final
- // \0 to terminate.
- match env {
- Some(env) => {
- let mut blk = ~[];
-
- for pair in env.iter() {
- let kv = format!("{}={}", pair.first(), pair.second());
- blk.push_all(kv.as_bytes());
- blk.push(0);
- }
-
- blk.push(0);
-
- blk.as_imm_buf(|p, _len| unsafe { cb(cast::transmute(p)) })
- }
- _ => cb(ptr::mut_null())
- }
-}
-
-fn with_dirp<T>(d: Option<&Path>, cb: |*libc::c_char| -> T) -> T {
- match d {
- Some(dir) => dir.with_c_str(|buf| cb(buf)),
- None => cb(ptr::null())
- }
-}
-
-#[cfg(windows)]
-fn free_handle(handle: *()) {
- unsafe {
- libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
- }
-}
-
-#[cfg(unix)]
-fn free_handle(_handle: *()) {
- // unix has no process handle object, just a pid
-}
-
-/**
- * Waits for a process to exit and returns the exit code, failing
- * if there is no process with the specified id.
- *
- * Note that this is private to avoid race conditions on unix where if
- * a user calls waitpid(some_process.get_id()) then some_process.finish()
- * and some_process.destroy() and some_process.finalize() will then either
- * operate on a none-existent process or, even worse, on a newer process
- * with the same id.
- */
-fn waitpid(pid: pid_t) -> int {
- return waitpid_os(pid);
-
- #[cfg(windows)]
- fn waitpid_os(pid: pid_t) -> int {
- use libc::types::os::arch::extra::DWORD;
- use libc::consts::os::extra::{
- SYNCHRONIZE,
- PROCESS_QUERY_INFORMATION,
- FALSE,
- STILL_ACTIVE,
- INFINITE,
- WAIT_FAILED
- };
- use libc::funcs::extra::kernel32::{
- OpenProcess,
- GetExitCodeProcess,
- CloseHandle,
- WaitForSingleObject
- };
-
- unsafe {
-
- let process = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
- FALSE,
- pid as DWORD);
- if process.is_null() {
- fail!("failure in OpenProcess: {}", os::last_os_error());
- }
-
- loop {
- let mut status = 0;
- if GetExitCodeProcess(process, &mut status) == FALSE {
- CloseHandle(process);
- fail!("failure in GetExitCodeProcess: {}", os::last_os_error());
- }
- if status != STILL_ACTIVE {
- CloseHandle(process);
- return status as int;
- }
- if WaitForSingleObject(process, INFINITE) == WAIT_FAILED {
- CloseHandle(process);
- fail!("failure in WaitForSingleObject: {}", os::last_os_error());
- }
- }
- }
- }
-
- #[cfg(unix)]
- fn waitpid_os(pid: pid_t) -> int {
- use libc::funcs::posix01::wait::*;
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- fn WIFEXITED(status: i32) -> bool {
- (status & 0xffi32) == 0i32
- }
-
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn WIFEXITED(status: i32) -> bool {
- (status & 0x7fi32) == 0i32
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- fn WEXITSTATUS(status: i32) -> i32 {
- (status >> 8i32) & 0xffi32
- }
-
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn WEXITSTATUS(status: i32) -> i32 {
- status >> 8i32
- }
-
- let mut status = 0 as c_int;
- if unsafe { waitpid(pid, &mut status, 0) } == -1 {
- fail!("failure in waitpid: {}", os::last_os_error());
- }
-
- return if WIFEXITED(status) {
- WEXITSTATUS(status) as int
- } else {
- 1
- };
- }
-}
-
-#[cfg(test)]
-mod tests {
-
- #[test] #[cfg(windows)]
- fn test_make_command_line() {
- use super::make_command_line;
- assert_eq!(
- make_command_line("prog", [~"aaa", ~"bbb", ~"ccc"]),
- ~"prog aaa bbb ccc"
- );
- assert_eq!(
- make_command_line("C:\\Program Files\\blah\\blah.exe", [~"aaa"]),
- ~"\"C:\\Program Files\\blah\\blah.exe\" aaa"
- );
- assert_eq!(
- make_command_line("C:\\Program Files\\test", [~"aa\"bb"]),
- ~"\"C:\\Program Files\\test\" aa\\\"bb"
- );
- assert_eq!(
- make_command_line("echo", [~"a b c"]),
- ~"echo \"a b c\""
- );
- }
-
- // Currently most of the tests of this functionality live inside std::run,
- // but they may move here eventually as a non-blocking backend is added to
- // std::run
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Synchronous DNS Resolution
-
-Contains the functionality to perform DNS resolution in a style related to
-getaddrinfo()
-
-*/
-
-use option::{Option, Some, None};
-use result::{Ok, Err};
-use io::{io_error};
-use io::net::ip::{SocketAddr, IpAddr};
-use rt::rtio::{IoFactory, with_local_io};
-use vec::ImmutableVector;
-
-/// Hints to the types of sockets that are desired when looking up hosts
-pub enum SocketType {
- Stream, Datagram, Raw
-}
-
-/// Flags which can be or'd into the `flags` field of a `Hint`. These are used
-/// to manipulate how a query is performed.
-///
-/// The meaning of each of these flags can be found with `man -s 3 getaddrinfo`
-pub enum Flag {
- AddrConfig,
- All,
- CanonName,
- NumericHost,
- NumericServ,
- Passive,
- V4Mapped,
-}
-
-/// A transport protocol associated with either a hint or a return value of
-/// `lookup`
-pub enum Protocol {
- TCP, UDP
-}
-
-/// This structure is used to provide hints when fetching addresses for a
-/// remote host to control how the lookup is performed.
-///
-/// For details on these fields, see their corresponding definitions via
-/// `man -s 3 getaddrinfo`
-pub struct Hint {
- family: uint,
- socktype: Option<SocketType>,
- protocol: Option<Protocol>,
- flags: uint,
-}
-
-pub struct Info {
- address: SocketAddr,
- family: uint,
- socktype: Option<SocketType>,
- protocol: Option<Protocol>,
- flags: uint,
-}
-
-/// Easy name resolution. Given a hostname, returns the list of IP addresses for
-/// that hostname.
-///
-/// # Failure
-///
-/// On failure, this will raise on the `io_error` condition.
-pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
- lookup(Some(host), None, None).map(|a| a.map(|i| i.address.ip))
-}
-
-/// Full-fleged resolution. This function will perform a synchronous call to
-/// getaddrinfo, controlled by the parameters
-///
-/// # Arguments
-///
-/// * hostname - an optional hostname to lookup against
-/// * servname - an optional service name, listed in the system services
-/// * hint - see the hint structure, and "man -s 3 getaddrinfo", for how this
-/// controls lookup
-///
-/// # Failure
-///
-/// On failure, this will raise on the `io_error` condition.
-///
-/// XXX: this is not public because the `Hint` structure is not ready for public
-/// consumption just yet.
-fn lookup(hostname: Option<&str>, servname: Option<&str>,
- hint: Option<Hint>) -> Option<~[Info]> {
- with_local_io(|io| {
- match io.get_host_addresses(hostname, servname, hint) {
- Ok(i) => Some(i),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
-}
-
-#[cfg(test)]
-mod test {
- use option::Some;
- use io::net::ip::Ipv4Addr;
- use super::*;
-
- #[test]
- #[ignore(cfg(target_os="android"))] // cannot give tcp/ip permission without help of apk
- fn dns_smoke_test() {
- let ipaddrs = get_host_addresses("localhost").unwrap();
- let mut found_local = false;
- let local_addr = &Ipv4Addr(127, 0, 0, 1);
- for addr in ipaddrs.iter() {
- found_local = found_local || addr == local_addr;
- }
- assert!(found_local);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::Container;
-use from_str::FromStr;
-use option::{Option, None, Some};
-use to_str::ToStr;
-use vec::{MutableCloneableVector, ImmutableVector};
-
-pub type Port = u16;
-
-#[deriving(Eq, TotalEq, Clone)]
-pub enum IpAddr {
- Ipv4Addr(u8, u8, u8, u8),
- Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
-}
-
-impl ToStr for IpAddr {
- fn to_str(&self) -> ~str {
- match *self {
- Ipv4Addr(a, b, c, d) =>
- format!("{}.{}.{}.{}", a, b, c, d),
-
- // Ipv4 Compatible address
- Ipv6Addr(0, 0, 0, 0, 0, 0, g, h) => {
- format!("::{}.{}.{}.{}", (g >> 8) as u8, g as u8,
- (h >> 8) as u8, h as u8)
- }
-
- // Ipv4-Mapped address
- Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, g, h) => {
- format!("::FFFF:{}.{}.{}.{}", (g >> 8) as u8, g as u8,
- (h >> 8) as u8, h as u8)
- }
-
- Ipv6Addr(a, b, c, d, e, f, g, h) =>
- format!("{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", a, b, c, d, e, f, g, h)
- }
- }
-}
-
-#[deriving(Eq, TotalEq, Clone)]
-pub struct SocketAddr {
- ip: IpAddr,
- port: Port,
-}
-
-
-impl ToStr for SocketAddr {
- fn to_str(&self) -> ~str {
- match self.ip {
- Ipv4Addr(..) => format!("{}:{}", self.ip.to_str(), self.port),
- Ipv6Addr(..) => format!("[{}]:{}", self.ip.to_str(), self.port),
- }
- }
-}
-
-struct Parser<'self> {
- // parsing as ASCII, so can use byte array
- s: &'self [u8],
- pos: uint,
-}
-
-impl<'self> Parser<'self> {
- fn new(s: &'self str) -> Parser<'self> {
- Parser {
- s: s.as_bytes(),
- pos: 0,
- }
- }
-
- fn is_eof(&self) -> bool {
- self.pos == self.s.len()
- }
-
- // Commit only if parser returns Some
- fn read_atomically<T>(&mut self, cb: |&mut Parser| -> Option<T>)
- -> Option<T> {
- let pos = self.pos;
- let r = cb(self);
- if r.is_none() {
- self.pos = pos;
- }
- r
- }
-
- // Commit only if parser read till EOF
- fn read_till_eof<T>(&mut self, cb: |&mut Parser| -> Option<T>)
- -> Option<T> {
- self.read_atomically(|p| cb(p).filtered(|_| p.is_eof()))
- }
-
- // Return result of first successful parser
- fn read_or<T>(&mut self, parsers: &[|&mut Parser| -> Option<T>])
- -> Option<T> {
- for pf in parsers.iter() {
- match self.read_atomically(|p: &mut Parser| (*pf)(p)) {
- Some(r) => return Some(r),
- None => {}
- }
- }
- None
- }
-
- // Apply 3 parsers sequentially
- fn read_seq_3<A,
- B,
- C>(
- &mut self,
- pa: |&mut Parser| -> Option<A>,
- pb: |&mut Parser| -> Option<B>,
- pc: |&mut Parser| -> Option<C>)
- -> Option<(A, B, C)> {
- self.read_atomically(|p| {
- let a = pa(p);
- let b = if a.is_some() { pb(p) } else { None };
- let c = if b.is_some() { pc(p) } else { None };
- match (a, b, c) {
- (Some(a), Some(b), Some(c)) => Some((a, b, c)),
- _ => None
- }
- })
- }
-
- // Read next char
- fn read_char(&mut self) -> Option<char> {
- if self.is_eof() {
- None
- } else {
- let r = self.s[self.pos] as char;
- self.pos += 1;
- Some(r)
- }
- }
-
- // Return char and advance iff next char is equal to requested
- fn read_given_char(&mut self, c: char) -> Option<char> {
- self.read_atomically(|p| {
- p.read_char().filtered(|&next| next == c)
- })
- }
-
- // Read digit
- fn read_digit(&mut self, radix: u8) -> Option<u8> {
- fn parse_digit(c: char, radix: u8) -> Option<u8> {
- let c = c as u8;
- // assuming radix is either 10 or 16
- if c >= '0' as u8 && c <= '9' as u8 {
- Some((c - '0' as u8) as u8)
- } else if radix > 10 && c >= 'a' as u8 && c < 'a' as u8 + (radix - 10) {
- Some((c - 'a' as u8 + 10) as u8)
- } else if radix > 10 && c >= 'A' as u8 && c < 'A' as u8 + (radix - 10) {
- Some((c - 'A' as u8 + 10) as u8)
- } else {
- None
- }
- }
-
- self.read_atomically(|p| {
- p.read_char().and_then(|c| parse_digit(c, radix))
- })
- }
-
- fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
- let mut r = 0u32;
- let mut digit_count = 0;
- loop {
- match self.read_digit(radix) {
- Some(d) => {
- r = r * (radix as u32) + (d as u32);
- digit_count += 1;
- if digit_count > max_digits || r >= upto {
- return None
- }
- }
- None => {
- if digit_count == 0 {
- return None
- } else {
- return Some(r)
- }
- }
- };
- }
- }
-
- // Read number, failing if max_digits of number value exceeded
- fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
- self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto))
- }
-
- fn read_ipv4_addr_impl(&mut self) -> Option<IpAddr> {
- let mut bs = [0u8, ..4];
- let mut i = 0;
- while i < 4 {
- if i != 0 && self.read_given_char('.').is_none() {
- return None;
- }
-
- let octet = self.read_number(10, 3, 0x100).map(|n| n as u8);
- match octet {
- Some(d) => bs[i] = d,
- None => return None,
- };
- i += 1;
- }
- Some(Ipv4Addr(bs[0], bs[1], bs[2], bs[3]))
- }
-
- // Read IPv4 address
- fn read_ipv4_addr(&mut self) -> Option<IpAddr> {
- self.read_atomically(|p| p.read_ipv4_addr_impl())
- }
-
- fn read_ipv6_addr_impl(&mut self) -> Option<IpAddr> {
- fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> IpAddr {
- assert!(head.len() + tail.len() <= 8);
- let mut gs = [0u16, ..8];
- gs.copy_from(head);
- gs.mut_slice(8 - tail.len(), 8).copy_from(tail);
- Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
- }
-
- fn read_groups(p: &mut Parser, groups: &mut [u16, ..8], limit: uint) -> (uint, bool) {
- let mut i = 0;
- while i < limit {
- if i < limit - 1 {
- let ipv4 = p.read_atomically(|p| {
- if i == 0 || p.read_given_char(':').is_some() {
- p.read_ipv4_addr()
- } else {
- None
- }
- });
- match ipv4 {
- Some(Ipv4Addr(a, b, c, d)) => {
- groups[i + 0] = (a as u16 << 8) | (b as u16);
- groups[i + 1] = (c as u16 << 8) | (d as u16);
- return (i + 2, true);
- }
- _ => {}
- }
- }
-
- let group = p.read_atomically(|p| {
- if i == 0 || p.read_given_char(':').is_some() {
- p.read_number(16, 4, 0x10000).map(|n| n as u16)
- } else {
- None
- }
- });
- match group {
- Some(g) => groups[i] = g,
- None => return (i, false)
- }
- i += 1;
- }
- (i, false)
- }
-
- let mut head = [0u16, ..8];
- let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
-
- if head_size == 8 {
- return Some(Ipv6Addr(
- head[0], head[1], head[2], head[3],
- head[4], head[5], head[6], head[7]))
- }
-
- // IPv4 part is not allowed before `::`
- if head_ipv4 {
- return None
- }
-
- // read `::` if previous code parsed less than 8 groups
- if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() {
- return None;
- }
-
- let mut tail = [0u16, ..8];
- let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
- Some(ipv6_addr_from_head_tail(head.slice(0, head_size), tail.slice(0, tail_size)))
- }
-
- fn read_ipv6_addr(&mut self) -> Option<IpAddr> {
- self.read_atomically(|p| p.read_ipv6_addr_impl())
- }
-
- fn read_ip_addr(&mut self) -> Option<IpAddr> {
- let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
- let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
- self.read_or([ipv4_addr, ipv6_addr])
- }
-
- fn read_socket_addr(&mut self) -> Option<SocketAddr> {
- let ip_addr = |p: &mut Parser| {
- let ipv4_p = |p: &mut Parser| p.read_ip_addr();
- let ipv6_p = |p: &mut Parser| {
- let open_br = |p: &mut Parser| p.read_given_char('[');
- let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
- let clos_br = |p: &mut Parser| p.read_given_char(']');
- p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
- .map(|t| match t { (_, ip, _) => ip })
- };
- p.read_or([ipv4_p, ipv6_p])
- };
- let colon = |p: &mut Parser| p.read_given_char(':');
- let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
-
- // host, colon, port
- self.read_seq_3::<IpAddr, char, u16>(ip_addr, colon, port)
- .map(|t| match t { (ip, _, port) => SocketAddr { ip: ip, port: port } })
- }
-}
-
-impl FromStr for IpAddr {
- fn from_str(s: &str) -> Option<IpAddr> {
- Parser::new(s).read_till_eof(|p| p.read_ip_addr())
- }
-}
-
-impl FromStr for SocketAddr {
- fn from_str(s: &str) -> Option<SocketAddr> {
- Parser::new(s).read_till_eof(|p| p.read_socket_addr())
- }
-}
-
-
-#[cfg(test)]
-mod test {
- use super::*;
- use from_str::FromStr;
- use option::{Option, Some, None};
-
- #[test]
- fn test_from_str_ipv4() {
- assert_eq!(Some(Ipv4Addr(127, 0, 0, 1)), FromStr::from_str("127.0.0.1"));
- assert_eq!(Some(Ipv4Addr(255, 255, 255, 255)), FromStr::from_str("255.255.255.255"));
- assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
-
- // out of range
- let none: Option<IpAddr> = FromStr::from_str("256.0.0.1");
- assert_eq!(None, none);
- // too short
- let none: Option<IpAddr> = FromStr::from_str("255.0.0");
- assert_eq!(None, none);
- // too long
- let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2");
- assert_eq!(None, none);
- // no number between dots
- let none: Option<IpAddr> = FromStr::from_str("255.0..1");
- assert_eq!(None, none);
- }
-
- #[test]
- fn test_from_str_ipv6() {
- assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("0:0:0:0:0:0:0:0"));
- assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("0:0:0:0:0:0:0:1"));
-
- assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("::1"));
- assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("::"));
-
- assert_eq!(Some(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
- FromStr::from_str("2a02:6b8::11:11"));
-
- // too long group
- let none: Option<IpAddr> = FromStr::from_str("::00000");
- assert_eq!(None, none);
- // too short
- let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7");
- assert_eq!(None, none);
- // too long
- let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9");
- assert_eq!(None, none);
- // triple colon
- let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8");
- assert_eq!(None, none);
- // two double colons
- let none: Option<IpAddr> = FromStr::from_str("1:2::6::8");
- assert_eq!(None, none);
- }
-
- #[test]
- fn test_from_str_ipv4_in_ipv6() {
- assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)),
- FromStr::from_str("::192.0.2.33"));
- assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
- FromStr::from_str("::FFFF:192.0.2.33"));
- assert_eq!(Some(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
- FromStr::from_str("64:ff9b::192.0.2.33"));
- assert_eq!(Some(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
- FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
-
- // colon after v4
- let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
- assert_eq!(None, none);
- // not enought groups
- let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
- assert_eq!(None, none);
- // too many groups
- let none: Option<IpAddr> =
- FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1");
- assert_eq!(None, none);
- }
-
- #[test]
- fn test_from_str_socket_addr() {
- assert_eq!(Some(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }),
- FromStr::from_str("77.88.21.11:80"));
- assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }),
- FromStr::from_str("[2a02:6b8:0:1::1]:53"));
- assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }),
- FromStr::from_str("[::127.0.0.1]:22"));
-
- // without port
- let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1");
- assert_eq!(None, none);
- // without port
- let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:");
- assert_eq!(None, none);
- // wrong brackets around v4
- let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22");
- assert_eq!(None, none);
- // port out of range
- let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456");
- assert_eq!(None, none);
- }
-
- #[test]
- fn ipv6_addr_to_str() {
- let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
- assert!(a1.to_str() == ~"::ffff:192.0.2.128" || a1.to_str() == ~"::FFFF:192.0.2.128");
- assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_str(), ~"8:9:a:b:c:d:e:f");
- }
-
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub use self::addrinfo::get_host_addresses;
-
-pub mod addrinfo;
-pub mod tcp;
-pub mod udp;
-pub mod ip;
-#[cfg(unix)]
-pub mod unix;
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use option::{Option, Some, None};
-use result::{Ok, Err};
-use io::net::ip::SocketAddr;
-use io::{Reader, Writer, Listener, Acceptor};
-use io::{io_error, EndOfFile};
-use rt::rtio::{IoFactory, with_local_io,
- RtioSocket, RtioTcpListener, RtioTcpAcceptor, RtioTcpStream};
-
-pub struct TcpStream {
- priv obj: ~RtioTcpStream
-}
-
-impl TcpStream {
- fn new(s: ~RtioTcpStream) -> TcpStream {
- TcpStream { obj: s }
- }
-
- pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
- with_local_io(|io| {
- match io.tcp_connect(addr) {
- Ok(s) => Some(TcpStream::new(s)),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-
- pub fn peer_name(&mut self) -> Option<SocketAddr> {
- match self.obj.peer_name() {
- Ok(pn) => Some(pn),
- Err(ioerr) => {
- debug!("failed to get peer name: {:?}", ioerr);
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-
- pub fn socket_name(&mut self) -> Option<SocketAddr> {
- match self.obj.socket_name() {
- Ok(sn) => Some(sn),
- Err(ioerr) => {
- debug!("failed to get socket name: {:?}", ioerr);
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-impl Reader for TcpStream {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- match self.obj.read(buf) {
- Ok(read) => Some(read),
- Err(ioerr) => {
- // EOF is indicated by returning None
- if ioerr.kind != EndOfFile {
- io_error::cond.raise(ioerr);
- }
- return None;
- }
- }
- }
-
- fn eof(&mut self) -> bool { fail!() }
-}
-
-impl Writer for TcpStream {
- fn write(&mut self, buf: &[u8]) {
- match self.obj.write(buf) {
- Ok(_) => (),
- Err(ioerr) => io_error::cond.raise(ioerr),
- }
- }
-}
-
-pub struct TcpListener {
- priv obj: ~RtioTcpListener
-}
-
-impl TcpListener {
- pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
- with_local_io(|io| {
- match io.tcp_bind(addr) {
- Ok(l) => Some(TcpListener { obj: l }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-
- pub fn socket_name(&mut self) -> Option<SocketAddr> {
- match self.obj.socket_name() {
- Ok(sn) => Some(sn),
- Err(ioerr) => {
- debug!("failed to get socket name: {:?}", ioerr);
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-impl Listener<TcpStream, TcpAcceptor> for TcpListener {
- fn listen(self) -> Option<TcpAcceptor> {
- match self.obj.listen() {
- Ok(acceptor) => Some(TcpAcceptor { obj: acceptor }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-pub struct TcpAcceptor {
- priv obj: ~RtioTcpAcceptor
-}
-
-impl Acceptor<TcpStream> for TcpAcceptor {
- fn accept(&mut self) -> Option<TcpStream> {
- match self.obj.accept() {
- Ok(s) => Some(TcpStream::new(s)),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use cell::Cell;
- use rt::test::*;
- use io::net::ip::{Ipv4Addr, SocketAddr};
- use io::*;
- use prelude::*;
- use rt::comm::oneshot;
-
- #[test] #[ignore]
- fn bind_error() {
- do run_in_mt_newsched_task {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert!(e.kind == PermissionDenied);
- called = true;
- }).inside(|| {
- let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
- let listener = TcpListener::bind(addr);
- assert!(listener.is_none());
- });
- assert!(called);
- }
- }
-
- #[test]
- fn connect_error() {
- do run_in_mt_newsched_task {
- let mut called = false;
- io_error::cond.trap(|e| {
- let expected_error = if cfg!(unix) {
- ConnectionRefused
- } else {
- // On Win32, opening port 1 gives WSAEADDRNOTAVAIL error.
- OtherIoError
- };
- assert_eq!(e.kind, expected_error);
- called = true;
- }).inside(|| {
- let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
- let stream = TcpStream::connect(addr);
- assert!(stream.is_none());
- });
- assert!(called);
- }
- }
-
- #[test]
- fn smoke_test_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let mut buf = [0];
- stream.read(buf);
- assert!(buf[0] == 99);
- }
-
- do spawntask {
- port.take().recv();
- let mut stream = TcpStream::connect(addr);
- stream.write([99]);
- }
- }
- }
-
- #[test]
- fn smoke_test_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let mut buf = [0];
- stream.read(buf);
- assert!(buf[0] == 99);
- }
-
- do spawntask {
- port.take().recv();
- let mut stream = TcpStream::connect(addr);
- stream.write([99]);
- }
- }
- }
-
- #[test]
- fn read_eof_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let mut buf = [0];
- let nread = stream.read(buf);
- assert!(nread.is_none());
- }
-
- do spawntask {
- port.take().recv();
- let _stream = TcpStream::connect(addr);
- // Close
- }
- }
- }
-
- #[test]
- fn read_eof_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let mut buf = [0];
- let nread = stream.read(buf);
- assert!(nread.is_none());
- }
-
- do spawntask {
- port.take().recv();
- let _stream = TcpStream::connect(addr);
- // Close
- }
- }
- }
-
- #[test]
- fn read_eof_twice_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let mut buf = [0];
- let nread = stream.read(buf);
- assert!(nread.is_none());
- io_error::cond.trap(|e| {
- if cfg!(windows) {
- assert_eq!(e.kind, NotConnected);
- } else {
- fail!();
- }
- }).inside(|| {
- let nread = stream.read(buf);
- assert!(nread.is_none());
- })
- }
-
- do spawntask {
- port.take().recv();
- let _stream = TcpStream::connect(addr);
- // Close
- }
- }
- }
-
- #[test]
- fn read_eof_twice_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let mut buf = [0];
- let nread = stream.read(buf);
- assert!(nread.is_none());
- io_error::cond.trap(|e| {
- if cfg!(windows) {
- assert_eq!(e.kind, NotConnected);
- } else {
- fail!();
- }
- }).inside(|| {
- let nread = stream.read(buf);
- assert!(nread.is_none());
- })
- }
-
- do spawntask {
- port.take().recv();
- let _stream = TcpStream::connect(addr);
- // Close
- }
- }
- }
-
- #[test]
- fn write_close_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let buf = [0];
- loop {
- let mut stop = false;
- io_error::cond.trap(|e| {
- // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
- // on windows
- assert!(e.kind == ConnectionReset ||
- e.kind == BrokenPipe ||
- e.kind == ConnectionAborted,
- "unknown error: {:?}", e);
- stop = true;
- }).inside(|| {
- stream.write(buf);
- });
- if stop { break }
- }
- }
-
- do spawntask {
- port.take().recv();
- let _stream = TcpStream::connect(addr);
- // Close
- }
- }
- }
-
- #[test]
- fn write_close_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- let mut stream = acceptor.accept();
- let buf = [0];
- loop {
- let mut stop = false;
- io_error::cond.trap(|e| {
- // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
- // on windows
- assert!(e.kind == ConnectionReset ||
- e.kind == BrokenPipe ||
- e.kind == ConnectionAborted,
- "unknown error: {:?}", e);
- stop = true;
- }).inside(|| {
- stream.write(buf);
- });
- if stop { break }
- }
- }
-
- do spawntask {
- port.take().recv();
- let _stream = TcpStream::connect(addr);
- // Close
- }
- }
- }
-
- #[test]
- fn multiple_connect_serial_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- let max = 10;
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- for ref mut stream in acceptor.incoming().take(max) {
- let mut buf = [0];
- stream.read(buf);
- assert_eq!(buf[0], 99);
- }
- }
-
- do spawntask {
- port.take().recv();
- max.times(|| {
- let mut stream = TcpStream::connect(addr);
- stream.write([99]);
- });
- }
- }
- }
-
- #[test]
- fn multiple_connect_serial_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- let max = 10;
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- for ref mut stream in acceptor.incoming().take(max) {
- let mut buf = [0];
- stream.read(buf);
- assert_eq!(buf[0], 99);
- }
- }
-
- do spawntask {
- port.take().recv();
- max.times(|| {
- let mut stream = TcpStream::connect(addr);
- stream.write([99]);
- });
- }
- }
- }
-
- #[test]
- fn multiple_connect_interleaved_greedy_schedule_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- static MAX: int = 10;
- let (port, chan) = oneshot();
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
- let stream = Cell::new(stream);
- // Start another task to handle the connection
- do spawntask {
- let mut stream = stream.take();
- let mut buf = [0];
- stream.read(buf);
- assert!(buf[0] == i as u8);
- debug!("read");
- }
- }
- }
-
- port.recv();
- connect(0, addr);
-
- fn connect(i: int, addr: SocketAddr) {
- if i == MAX { return }
-
- do spawntask {
- debug!("connecting");
- let mut stream = TcpStream::connect(addr);
- // Connect again before writing
- connect(i + 1, addr);
- debug!("writing");
- stream.write([i as u8]);
- }
- }
- }
- }
-
- #[test]
- fn multiple_connect_interleaved_greedy_schedule_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- static MAX: int = 10;
- let (port, chan) = oneshot();
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
- let stream = Cell::new(stream);
- // Start another task to handle the connection
- do spawntask {
- let mut stream = stream.take();
- let mut buf = [0];
- stream.read(buf);
- assert!(buf[0] == i as u8);
- debug!("read");
- }
- }
- }
-
- port.recv();
- connect(0, addr);
-
- fn connect(i: int, addr: SocketAddr) {
- if i == MAX { return }
-
- do spawntask {
- debug!("connecting");
- let mut stream = TcpStream::connect(addr);
- // Connect again before writing
- connect(i + 1, addr);
- debug!("writing");
- stream.write([i as u8]);
- }
- }
- }
- }
-
- #[test]
- fn multiple_connect_interleaved_lazy_schedule_ip4() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip4();
- static MAX: int = 10;
- let (port, chan) = oneshot();
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- for stream in acceptor.incoming().take(MAX as uint) {
- let stream = Cell::new(stream);
- // Start another task to handle the connection
- do spawntask_later {
- let mut stream = stream.take();
- let mut buf = [0];
- stream.read(buf);
- assert!(buf[0] == 99);
- debug!("read");
- }
- }
- }
-
- port.recv();
- connect(0, addr);
-
- fn connect(i: int, addr: SocketAddr) {
- if i == MAX { return }
-
- do spawntask_later {
- debug!("connecting");
- let mut stream = TcpStream::connect(addr);
- // Connect again before writing
- connect(i + 1, addr);
- debug!("writing");
- stream.write([99]);
- }
- }
- }
- }
- #[test]
- fn multiple_connect_interleaved_lazy_schedule_ip6() {
- do run_in_mt_newsched_task {
- let addr = next_test_ip6();
- static MAX: int = 10;
- let (port, chan) = oneshot();
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
- for stream in acceptor.incoming().take(MAX as uint) {
- let stream = Cell::new(stream);
- // Start another task to handle the connection
- do spawntask_later {
- let mut stream = stream.take();
- let mut buf = [0];
- stream.read(buf);
- assert!(buf[0] == 99);
- debug!("read");
- }
- }
- }
-
- port.recv();
- connect(0, addr);
-
- fn connect(i: int, addr: SocketAddr) {
- if i == MAX { return }
-
- do spawntask_later {
- debug!("connecting");
- let mut stream = TcpStream::connect(addr);
- // Connect again before writing
- connect(i + 1, addr);
- debug!("writing");
- stream.write([99]);
- }
- }
- }
- }
-
- #[cfg(test)]
- fn socket_name(addr: SocketAddr) {
- do run_in_mt_newsched_task {
- do spawntask {
- let mut listener = TcpListener::bind(addr).unwrap();
-
- // Make sure socket_name gives
- // us the socket we binded to.
- let so_name = listener.socket_name();
- assert!(so_name.is_some());
- assert_eq!(addr, so_name.unwrap());
-
- }
- }
- }
-
- #[cfg(test)]
- fn peer_name(addr: SocketAddr) {
- do run_in_mt_newsched_task {
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = TcpListener::bind(addr).listen();
- chan.take().send(());
-
- acceptor.accept();
- }
-
- do spawntask {
- port.take().recv();
- let stream = TcpStream::connect(addr);
-
- assert!(stream.is_some());
- let mut stream = stream.unwrap();
-
- // Make sure peer_name gives us the
- // address/port of the peer we've
- // connected to.
- let peer_name = stream.peer_name();
- assert!(peer_name.is_some());
- assert_eq!(addr, peer_name.unwrap());
- }
- }
- }
-
- #[test]
- fn socket_and_peer_name_ip4() {
- peer_name(next_test_ip4());
- socket_name(next_test_ip4());
- }
-
- #[test]
- fn socket_and_peer_name_ip6() {
- // XXX: peer name is not consistent
- //peer_name(next_test_ip6());
- socket_name(next_test_ip6());
- }
-
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use option::{Option, Some, None};
-use result::{Ok, Err};
-use io::net::ip::SocketAddr;
-use io::{Reader, Writer};
-use io::{io_error, EndOfFile};
-use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, with_local_io};
-
-pub struct UdpSocket {
- priv obj: ~RtioUdpSocket
-}
-
-impl UdpSocket {
- pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
- with_local_io(|io| {
- match io.udp_bind(addr) {
- Ok(s) => Some(UdpSocket { obj: s }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-
- pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, SocketAddr)> {
- match self.obj.recvfrom(buf) {
- Ok((nread, src)) => Some((nread, src)),
- Err(ioerr) => {
- // EOF is indicated by returning None
- if ioerr.kind != EndOfFile {
- io_error::cond.raise(ioerr);
- }
- None
- }
- }
- }
-
- pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) {
- match self.obj.sendto(buf, dst) {
- Ok(_) => (),
- Err(ioerr) => io_error::cond.raise(ioerr),
- }
- }
-
- pub fn connect(self, other: SocketAddr) -> UdpStream {
- UdpStream { socket: self, connectedTo: other }
- }
-
- pub fn socket_name(&mut self) -> Option<SocketAddr> {
- match self.obj.socket_name() {
- Ok(sn) => Some(sn),
- Err(ioerr) => {
- debug!("failed to get socket name: {:?}", ioerr);
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-pub struct UdpStream {
- priv socket: UdpSocket,
- priv connectedTo: SocketAddr
-}
-
-impl UdpStream {
- pub fn as_socket<T>(&mut self, f: |&mut UdpSocket| -> T) -> T {
- f(&mut self.socket)
- }
-
- pub fn disconnect(self) -> UdpSocket { self.socket }
-}
-
-impl Reader for UdpStream {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- let peer = self.connectedTo;
- self.as_socket(|sock| {
- match sock.recvfrom(buf) {
- Some((_nread, src)) if src != peer => Some(0),
- Some((nread, _src)) => Some(nread),
- None => None,
- }
- })
- }
-
- fn eof(&mut self) -> bool { fail!() }
-}
-
-impl Writer for UdpStream {
- fn write(&mut self, buf: &[u8]) {
- self.as_socket(|sock| sock.sendto(buf, self.connectedTo));
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use rt::test::*;
- use io::net::ip::{Ipv4Addr, SocketAddr};
- use io::*;
- use option::{Some, None};
- use rt::comm::oneshot;
- use cell::Cell;
-
- #[test] #[ignore]
- fn bind_error() {
- do run_in_mt_newsched_task {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert!(e.kind == PermissionDenied);
- called = true;
- }).inside(|| {
- let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
- let socket = UdpSocket::bind(addr);
- assert!(socket.is_none());
- });
- assert!(called);
- }
- }
-
- #[test]
- fn socket_smoke_test_ip4() {
- do run_in_mt_newsched_task {
- let server_ip = next_test_ip4();
- let client_ip = next_test_ip4();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- match UdpSocket::bind(server_ip) {
- Some(ref mut server) => {
- chan.take().send(());
- let mut buf = [0];
- match server.recvfrom(buf) {
- Some((nread, src)) => {
- assert_eq!(nread, 1);
- assert_eq!(buf[0], 99);
- assert_eq!(src, client_ip);
- }
- None => fail!()
- }
- }
- None => fail!()
- }
- }
-
- do spawntask {
- match UdpSocket::bind(client_ip) {
- Some(ref mut client) => {
- port.take().recv();
- client.sendto([99], server_ip)
- }
- None => fail!()
- }
- }
- }
- }
-
- #[test]
- fn socket_smoke_test_ip6() {
- do run_in_mt_newsched_task {
- let server_ip = next_test_ip6();
- let client_ip = next_test_ip6();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- match UdpSocket::bind(server_ip) {
- Some(ref mut server) => {
- chan.take().send(());
- let mut buf = [0];
- match server.recvfrom(buf) {
- Some((nread, src)) => {
- assert_eq!(nread, 1);
- assert_eq!(buf[0], 99);
- assert_eq!(src, client_ip);
- }
- None => fail!()
- }
- }
- None => fail!()
- }
- }
-
- do spawntask {
- match UdpSocket::bind(client_ip) {
- Some(ref mut client) => {
- port.take().recv();
- client.sendto([99], server_ip)
- }
- None => fail!()
- }
- }
- }
- }
-
- #[test]
- fn stream_smoke_test_ip4() {
- do run_in_mt_newsched_task {
- let server_ip = next_test_ip4();
- let client_ip = next_test_ip4();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- match UdpSocket::bind(server_ip) {
- Some(server) => {
- let server = ~server;
- let mut stream = server.connect(client_ip);
- chan.take().send(());
- let mut buf = [0];
- match stream.read(buf) {
- Some(nread) => {
- assert_eq!(nread, 1);
- assert_eq!(buf[0], 99);
- }
- None => fail!()
- }
- }
- None => fail!()
- }
- }
-
- do spawntask {
- match UdpSocket::bind(client_ip) {
- Some(client) => {
- let client = ~client;
- let mut stream = client.connect(server_ip);
- port.take().recv();
- stream.write([99]);
- }
- None => fail!()
- }
- }
- }
- }
-
- #[test]
- fn stream_smoke_test_ip6() {
- do run_in_mt_newsched_task {
- let server_ip = next_test_ip6();
- let client_ip = next_test_ip6();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- match UdpSocket::bind(server_ip) {
- Some(server) => {
- let server = ~server;
- let mut stream = server.connect(client_ip);
- chan.take().send(());
- let mut buf = [0];
- match stream.read(buf) {
- Some(nread) => {
- assert_eq!(nread, 1);
- assert_eq!(buf[0], 99);
- }
- None => fail!()
- }
- }
- None => fail!()
- }
- }
-
- do spawntask {
- match UdpSocket::bind(client_ip) {
- Some(client) => {
- let client = ~client;
- let mut stream = client.connect(server_ip);
- port.take().recv();
- stream.write([99]);
- }
- None => fail!()
- }
- }
- }
- }
-
- #[cfg(test)]
- fn socket_name(addr: SocketAddr) {
- do run_in_mt_newsched_task {
- do spawntask {
- let server = UdpSocket::bind(addr);
-
- assert!(server.is_some());
- let mut server = server.unwrap();
-
- // Make sure socket_name gives
- // us the socket we binded to.
- let so_name = server.socket_name();
- assert!(so_name.is_some());
- assert_eq!(addr, so_name.unwrap());
-
- }
- }
- }
-
- #[test]
- fn socket_name_ip4() {
- socket_name(next_test_ip4());
- }
-
- #[test]
- fn socket_name_ip6() {
- socket_name(next_test_ip6());
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Named pipes
-
-This module contains the ability to communicate over named pipes with
-synchronous I/O. On windows, this corresponds to talking over a Named Pipe,
-while on Unix it corresponds to UNIX domain sockets.
-
-These pipes are similar to TCP in the sense that you can have both a stream to a
-server and a server itself. The server provided accepts other `UnixStream`
-instances as clients.
-
-*/
-
-use prelude::*;
-
-use c_str::ToCStr;
-use rt::rtio::{IoFactory, RtioUnixListener, with_local_io};
-use rt::rtio::{RtioUnixAcceptor, RtioPipe};
-use io::pipe::PipeStream;
-use io::{io_error, Listener, Acceptor, Reader, Writer};
-
-/// A stream which communicates over a named pipe.
-pub struct UnixStream {
- priv obj: PipeStream,
-}
-
-impl UnixStream {
- fn new(obj: ~RtioPipe) -> UnixStream {
- UnixStream { obj: PipeStream::new(obj) }
- }
-
- /// Connect to a pipe named by `path`. This will attempt to open a
- /// connection to the underlying socket.
- ///
- /// The returned stream will be closed when the object falls out of scope.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if the connection
- /// could not be made.
- ///
- /// # Example
- ///
- /// use std::io::net::unix::UnixStream;
- ///
- /// let server = Path("path/to/my/socket");
- /// let mut stream = UnixStream::connect(&server);
- /// stream.write([1, 2, 3]);
- ///
- pub fn connect<P: ToCStr>(path: &P) -> Option<UnixStream> {
- with_local_io(|io| {
- match io.unix_connect(&path.to_c_str()) {
- Ok(s) => Some(UnixStream::new(s)),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-}
-
-impl Reader for UnixStream {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.obj.read(buf) }
- fn eof(&mut self) -> bool { self.obj.eof() }
-}
-
-impl Writer for UnixStream {
- fn write(&mut self, buf: &[u8]) { self.obj.write(buf) }
-}
-
-pub struct UnixListener {
- priv obj: ~RtioUnixListener,
-}
-
-impl UnixListener {
-
- /// Creates a new listener, ready to receive incoming connections on the
- /// specified socket. The server will be named by `path`.
- ///
- /// This listener will be closed when it falls out of scope.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if the specified
- /// path could not be bound.
- ///
- /// # Example
- ///
- /// use std::io::net::unix::UnixListener;
- ///
- /// let server = Path("path/to/my/socket");
- /// let mut stream = UnixListener::bind(&server);
- /// for client in stream.incoming() {
- /// let mut client = client;
- /// client.write([1, 2, 3, 4]);
- /// }
- ///
- pub fn bind<P: ToCStr>(path: &P) -> Option<UnixListener> {
- with_local_io(|io| {
- match io.unix_bind(&path.to_c_str()) {
- Ok(s) => Some(UnixListener{ obj: s }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-}
-
-impl Listener<UnixStream, UnixAcceptor> for UnixListener {
- fn listen(self) -> Option<UnixAcceptor> {
- match self.obj.listen() {
- Ok(acceptor) => Some(UnixAcceptor { obj: acceptor }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-pub struct UnixAcceptor {
- priv obj: ~RtioUnixAcceptor,
-}
-
-impl Acceptor<UnixStream> for UnixAcceptor {
- fn accept(&mut self) -> Option<UnixStream> {
- match self.obj.accept() {
- Ok(s) => Some(UnixStream::new(s)),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use super::*;
- use cell::Cell;
- use rt::test::*;
- use io::*;
- use rt::comm::oneshot;
-
- fn smalltest(server: proc(UnixStream), client: proc(UnixStream)) {
- let server = Cell::new(server);
- let client = Cell::new(client);
- do run_in_mt_newsched_task {
- let server = Cell::new(server.take());
- let client = Cell::new(client.take());
- let path1 = next_test_unix();
- let path2 = path1.clone();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = UnixListener::bind(&path1).listen();
- chan.take().send(());
- server.take()(acceptor.accept().unwrap());
- }
-
- do spawntask {
- port.take().recv();
- client.take()(UnixStream::connect(&path2).unwrap());
- }
- }
- }
-
- #[test]
- fn bind_error() {
- do run_in_mt_newsched_task {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert!(e.kind == PermissionDenied);
- called = true;
- }).inside(|| {
- let listener = UnixListener::bind(&("path/to/nowhere"));
- assert!(listener.is_none());
- });
- assert!(called);
- }
- }
-
- #[test]
- fn connect_error() {
- do run_in_mt_newsched_task {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert_eq!(e.kind, OtherIoError);
- called = true;
- }).inside(|| {
- let stream = UnixStream::connect(&("path/to/nowhere"));
- assert!(stream.is_none());
- });
- assert!(called);
- }
- }
-
- #[test]
- fn smoke() {
- smalltest(proc(mut server) {
- let mut buf = [0];
- server.read(buf);
- assert!(buf[0] == 99);
- }, proc(mut client) {
- client.write([99]);
- })
- }
-
- #[test]
- fn read_eof() {
- smalltest(proc(mut server) {
- let mut buf = [0];
- assert!(server.read(buf).is_none());
- assert!(server.read(buf).is_none());
- }, proc(_client) {
- // drop the client
- })
- }
-
- #[test]
- fn write_begone() {
- smalltest(proc(mut server) {
- let buf = [0];
- let mut stop = false;
- while !stop{
- io_error::cond.trap(|e| {
- assert!(e.kind == BrokenPipe || e.kind == NotConnected,
- "unknown error {:?}", e);
- stop = true;
- }).inside(|| {
- server.write(buf);
- })
- }
- }, proc(_client) {
- // drop the client
- })
- }
-
- #[test]
- fn accept_lots() {
- do run_in_mt_newsched_task {
- let times = 10;
- let path1 = next_test_unix();
- let path2 = path1.clone();
- let (port, chan) = oneshot();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- do spawntask {
- let mut acceptor = UnixListener::bind(&path1).listen();
- chan.take().send(());
- times.times(|| {
- let mut client = acceptor.accept();
- let mut buf = [0];
- client.read(buf);
- assert_eq!(buf[0], 100);
- })
- }
-
- do spawntask {
- port.take().recv();
- times.times(|| {
- let mut stream = UnixStream::connect(&path2);
- stream.write([100]);
- })
- }
- }
- }
-
- #[test]
- fn path_exists() {
- do run_in_mt_newsched_task {
- let path = next_test_unix();
- let _acceptor = UnixListener::bind(&path).listen();
- assert!(path.exists());
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Implementations of I/O traits for the Option type
-//!
-//! I/O constructors return option types to allow errors to be handled.
-//! These implementations allow e.g. `Option<File>` to be used
-//! as a `Reader` without unwrapping the option first.
-
-use option::*;
-use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle};
-use super::{standard_error, PreviousIoError, io_error, IoError};
-
-fn prev_io_error() -> IoError {
- standard_error(PreviousIoError)
-}
-
-impl<W: Writer> Writer for Option<W> {
- fn write(&mut self, buf: &[u8]) {
- match *self {
- Some(ref mut writer) => writer.write(buf),
- None => io_error::cond.raise(prev_io_error())
- }
- }
-
- fn flush(&mut self) {
- match *self {
- Some(ref mut writer) => writer.flush(),
- None => io_error::cond.raise(prev_io_error())
- }
- }
-}
-
-impl<R: Reader> Reader for Option<R> {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- match *self {
- Some(ref mut reader) => reader.read(buf),
- None => {
- io_error::cond.raise(prev_io_error());
- None
- }
- }
- }
-
- fn eof(&mut self) -> bool {
- match *self {
- Some(ref mut reader) => reader.eof(),
- None => {
- io_error::cond.raise(prev_io_error());
- true
- }
- }
- }
-}
-
-impl<S: Seek> Seek for Option<S> {
- fn tell(&self) -> u64 {
- match *self {
- Some(ref seeker) => seeker.tell(),
- None => {
- io_error::cond.raise(prev_io_error());
- 0
- }
- }
- }
- fn seek(&mut self, pos: i64, style: SeekStyle) {
- match *self {
- Some(ref mut seeker) => seeker.seek(pos, style),
- None => io_error::cond.raise(prev_io_error())
- }
- }
-}
-
-impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for Option<L> {
- fn listen(self) -> Option<A> {
- match self {
- Some(listener) => listener.listen(),
- None => {
- io_error::cond.raise(prev_io_error());
- None
- }
- }
- }
-}
-
-impl<T, A: Acceptor<T>> Acceptor<T> for Option<A> {
- fn accept(&mut self) -> Option<T> {
- match *self {
- Some(ref mut acceptor) => acceptor.accept(),
- None => {
- io_error::cond.raise(prev_io_error());
- None
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use option::*;
- use super::super::mem::*;
- use rt::test::*;
- use super::super::{PreviousIoError, io_error};
-
- #[test]
- fn test_option_writer() {
- do run_in_mt_newsched_task {
- let mut writer: Option<MemWriter> = Some(MemWriter::new());
- writer.write([0, 1, 2]);
- writer.flush();
- assert_eq!(writer.unwrap().inner(), ~[0, 1, 2]);
- }
- }
-
- #[test]
- fn test_option_writer_error() {
- do run_in_mt_newsched_task {
- let mut writer: Option<MemWriter> = None;
-
- let mut called = false;
- io_error::cond.trap(|err| {
- assert_eq!(err.kind, PreviousIoError);
- called = true;
- }).inside(|| {
- writer.write([0, 0, 0]);
- });
- assert!(called);
-
- let mut called = false;
- io_error::cond.trap(|err| {
- assert_eq!(err.kind, PreviousIoError);
- called = true;
- }).inside(|| {
- writer.flush();
- });
- assert!(called);
- }
- }
-
- #[test]
- fn test_option_reader() {
- do run_in_mt_newsched_task {
- let mut reader: Option<MemReader> = Some(MemReader::new(~[0, 1, 2, 3]));
- let mut buf = [0, 0];
- reader.read(buf);
- assert_eq!(buf, [0, 1]);
- assert!(!reader.eof());
- }
- }
-
- #[test]
- fn test_option_reader_error() {
- let mut reader: Option<MemReader> = None;
- let mut buf = [];
-
- let mut called = false;
- io_error::cond.trap(|err| {
- assert_eq!(err.kind, PreviousIoError);
- called = true;
- }).inside(|| {
- reader.read(buf);
- });
- assert!(called);
-
- let mut called = false;
- io_error::cond.trap(|err| {
- assert_eq!(err.kind, PreviousIoError);
- called = true;
- }).inside(|| {
- assert!(reader.eof());
- });
- assert!(called);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Synchronous, in-memory pipes.
-//!
-//! Currently these aren't particularly useful, there only exists bindings
-//! enough so that pipes can be created to child processes.
-
-use prelude::*;
-use super::{Reader, Writer};
-use io::{io_error, EndOfFile};
-use io::native::file;
-use rt::rtio::{RtioPipe, with_local_io};
-
-pub struct PipeStream {
- priv obj: ~RtioPipe,
-}
-
-impl PipeStream {
- /// Consumes a file descriptor to return a pipe stream that will have
- /// synchronous, but non-blocking reads/writes. This is useful if the file
- /// descriptor is acquired via means other than the standard methods.
- ///
- /// This operation consumes ownership of the file descriptor and it will be
- /// closed once the object is deallocated.
- ///
- /// # Example
- ///
- /// use std::libc;
- /// use std::io::pipe;
- ///
- /// let mut pipe = PipeStream::open(libc::STDERR_FILENO);
- /// pipe.write(bytes!("Hello, stderr!"));
- ///
- /// # Failure
- ///
- /// If the pipe cannot be created, an error will be raised on the
- /// `io_error` condition.
- pub fn open(fd: file::fd_t) -> Option<PipeStream> {
- with_local_io(|io| {
- match io.pipe_open(fd) {
- Ok(obj) => Some(PipeStream { obj: obj }),
- Err(e) => {
- io_error::cond.raise(e);
- None
- }
- }
- })
- }
-
- pub fn new(inner: ~RtioPipe) -> PipeStream {
- PipeStream { obj: inner }
- }
-}
-
-impl Reader for PipeStream {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- match self.obj.read(buf) {
- Ok(read) => Some(read),
- Err(ioerr) => {
- // EOF is indicated by returning None
- if ioerr.kind != EndOfFile {
- io_error::cond.raise(ioerr);
- }
- return None;
- }
- }
- }
-
- fn eof(&mut self) -> bool { false }
-}
-
-impl Writer for PipeStream {
- fn write(&mut self, buf: &[u8]) {
- match self.obj.write(buf) {
- Ok(_) => (),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- }
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Bindings for executing child processes
-
-use prelude::*;
-use cell::Cell;
-
-use libc;
-use io;
-use io::io_error;
-use rt::rtio::{RtioProcess, IoFactory, with_local_io};
-
-use fmt;
-
-// windows values don't matter as long as they're at least one of unix's
-// TERM/KILL/INT signals
-#[cfg(windows)] pub static PleaseExitSignal: int = 15;
-#[cfg(windows)] pub static MustDieSignal: int = 9;
-#[cfg(not(windows))] pub static PleaseExitSignal: int = libc::SIGTERM as int;
-#[cfg(not(windows))] pub static MustDieSignal: int = libc::SIGKILL as int;
-
-pub struct Process {
- priv handle: ~RtioProcess,
- io: ~[Option<io::PipeStream>],
-}
-
-/// This configuration describes how a new process should be spawned. This is
-/// translated to libuv's own configuration
-pub struct ProcessConfig<'self> {
- /// Path to the program to run
- program: &'self str,
-
- /// Arguments to pass to the program (doesn't include the program itself)
- args: &'self [~str],
-
- /// Optional environment to specify for the program. If this is None, then
- /// it will inherit the current process's environment.
- env: Option<&'self [(~str, ~str)]>,
-
- /// Optional working directory for the new process. If this is None, then
- /// the current directory of the running process is inherited.
- cwd: Option<&'self str>,
-
- /// Any number of streams/file descriptors/pipes may be attached to this
- /// process. This list enumerates the file descriptors and such for the
- /// process to be spawned, and the file descriptors inherited will start at
- /// 0 and go to the length of this array.
- ///
- /// Standard file descriptors are:
- ///
- /// 0 - stdin
- /// 1 - stdout
- /// 2 - stderr
- io: &'self [StdioContainer]
-}
-
-/// Describes what to do with a standard io stream for a child process.
-pub enum StdioContainer {
- /// This stream will be ignored. This is the equivalent of attaching the
- /// stream to `/dev/null`
- Ignored,
-
- /// The specified file descriptor is inherited for the stream which it is
- /// specified for.
- InheritFd(libc::c_int),
-
- /// Creates a pipe for the specified file descriptor which will be created
- /// when the process is spawned.
- ///
- /// The first boolean argument is whether the pipe is readable, and the
- /// second is whether it is writable. These properties are from the view of
- /// the *child* process, not the parent process.
- CreatePipe(bool /* readable */, bool /* writable */),
-}
-
-/// Describes the result of a process after it has terminated.
-/// Note that Windows have no signals, so the result is usually ExitStatus.
-#[deriving(Eq)]
-pub enum ProcessExit {
- /// Normal termination with an exit status.
- ExitStatus(int),
-
- /// Termination by signal, with the signal number.
- ExitSignal(int),
-}
-
-impl fmt::Default for ProcessExit {
- /// Format a ProcessExit enum, to nicely present the information.
- fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) {
- match *obj {
- ExitStatus(code) => write!(f.buf, "exit code: {}", code),
- ExitSignal(code) => write!(f.buf, "signal: {}", code),
- }
- }
-}
-
-impl ProcessExit {
- /// Was termination successful? Signal termination not considered a success,
- /// and success is defined as a zero exit status.
- pub fn success(&self) -> bool {
- return self.matches_exit_status(0);
- }
-
- /// Checks whether this ProcessExit matches the given exit status.
- /// Termination by signal will never match an exit code.
- pub fn matches_exit_status(&self, wanted: int) -> bool {
- *self == ExitStatus(wanted)
- }
-}
-
-impl Process {
- /// Creates a new pipe initialized, but not bound to any particular
- /// source/destination
- pub fn new(config: ProcessConfig) -> Option<Process> {
- let config = Cell::new(config);
- with_local_io(|io| {
- match io.spawn(config.take()) {
- Ok((p, io)) => Some(Process{
- handle: p,
- io: io.move_iter().map(|p|
- p.map(|p| io::PipeStream::new(p))
- ).collect()
- }),
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- })
- }
-
- /// Returns the process id of this child process
- pub fn id(&self) -> libc::pid_t { self.handle.id() }
-
- /// Sends the specified signal to the child process, returning whether the
- /// signal could be delivered or not.
- ///
- /// Note that this is purely a wrapper around libuv's `uv_process_kill`
- /// function.
- ///
- /// If the signal delivery fails, then the `io_error` condition is raised on
- pub fn signal(&mut self, signal: int) {
- match self.handle.kill(signal) {
- Ok(()) => {}
- Err(err) => {
- io_error::cond.raise(err)
- }
- }
- }
-
- /// Wait for the child to exit completely, returning the status that it
- /// exited with. This function will continue to have the same return value
- /// after it has been called at least once.
- pub fn wait(&mut self) -> ProcessExit { self.handle.wait() }
-}
-
-impl Drop for Process {
- fn drop(&mut self) {
- // Close all I/O before exiting to ensure that the child doesn't wait
- // forever to print some text or something similar.
- for _ in range(0, self.io.len()) {
- self.io.pop();
- }
-
- self.wait();
- }
-}
-
-// Tests for this module can be found in the rtio-processes run-pass test, along
-// with the justification for why it's not located here.
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Signal handling
-
-This modules provides bindings to receive signals safely, built on top of the
-local I/O factory. There are a number of defined signals which can be caught,
-but not all signals will work across all platforms (windows doesn't have
-definitions for a number of signals.
-
-*/
-
-use clone::Clone;
-use comm::{Port, SharedChan, stream};
-use container::{Map, MutableMap};
-use hashmap;
-use io::io_error;
-use option::{Some, None};
-use result::{Err, Ok};
-use rt::rtio::{IoFactory, RtioSignal, with_local_io};
-
-#[repr(int)]
-#[deriving(Eq, IterBytes)]
-pub enum Signum {
- /// Equivalent to SIGBREAK, delivered when the user presses Ctrl-Break.
- Break = 21i,
- /// Equivalent to SIGHUP, delivered when the user closes the terminal
- /// window. On delivery of HangUp, the program is given approximately
- /// 10 seconds to perfom any cleanup. After that, Windows will
- /// unconditionally terminate it.
- HangUp = 1i,
- /// Equivalent to SIGINT, delivered when the user presses Ctrl-c.
- Interrupt = 2i,
- /// Equivalent to SIGQUIT, delivered when the user presses Ctrl-\.
- Quit = 3i,
- /// Equivalent to SIGTSTP, delivered when the user presses Ctrl-z.
- StopTemporarily = 20i,
- /// Equivalent to SIGUSR1.
- User1 = 10i,
- /// Equivalent to SIGUSR2.
- User2 = 12i,
- /// Equivalent to SIGWINCH, delivered when the console has been resized.
- /// WindowSizeChange may not be delivered in a timely manner; size change
- /// will only be detected when the cursor is being moved.
- WindowSizeChange = 28i,
-}
-
-/// Listener provides a port to listen for registered signals.
-///
-/// Listener automatically unregisters its handles once it is out of scope.
-/// However, clients can still unregister signums manually.
-///
-/// # Example
-///
-/// ```rust
-/// use std::io::signal::{Listener, Interrupt};
-///
-/// let mut listener = Listener::new();
-/// listener.register(signal::Interrupt);
-///
-/// do spawn {
-/// loop {
-/// match listener.port.recv() {
-/// Interrupt => println("Got Interrupt'ed"),
-/// _ => (),
-/// }
-/// }
-/// }
-///
-/// ```
-pub struct Listener {
- /// A map from signums to handles to keep the handles in memory
- priv handles: hashmap::HashMap<Signum, ~RtioSignal>,
- /// chan is where all the handles send signums, which are received by
- /// the clients from port.
- priv chan: SharedChan<Signum>,
-
- /// Clients of Listener can `recv()` from this port. This is exposed to
- /// allow selection over this port as well as manipulation of the port
- /// directly.
- port: Port<Signum>,
-}
-
-impl Listener {
- /// Creates a new listener for signals. Once created, signals are bound via
- /// the `register` method (otherwise nothing will ever be received)
- pub fn new() -> Listener {
- let (port, chan) = stream();
- Listener {
- chan: SharedChan::new(chan),
- port: port,
- handles: hashmap::HashMap::new(),
- }
- }
-
- /// Listen for a signal, returning true when successfully registered for
- /// signum. Signals can be received using `recv()`.
- ///
- /// Once a signal is registered, this listener will continue to receive
- /// notifications of signals until it is unregistered. This occurs
- /// regardless of the number of other listeners registered in other tasks
- /// (or on this task).
- ///
- /// Signals are still received if there is no task actively waiting for
- /// a signal, and a later call to `recv` will return the signal that was
- /// received while no task was waiting on it.
- ///
- /// # Failure
- ///
- /// If this function fails to register a signal handler, then an error will
- /// be raised on the `io_error` condition and the function will return
- /// false.
- pub fn register(&mut self, signum: Signum) -> bool {
- if self.handles.contains_key(&signum) {
- return true; // self is already listening to signum, so succeed
- }
- with_local_io(|io| {
- match io.signal(signum, self.chan.clone()) {
- Ok(w) => {
- self.handles.insert(signum, w);
- Some(())
- },
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
- None
- }
- }
- }).is_some()
- }
-
- /// Unregisters a signal. If this listener currently had a handler
- /// registered for the signal, then it will stop receiving any more
- /// notification about the signal. If the signal has already been received,
- /// it may still be returned by `recv`.
- pub fn unregister(&mut self, signum: Signum) {
- self.handles.pop(&signum);
- }
-}
-
-#[cfg(test)]
-mod test {
- use libc;
- use io::timer;
- use super::{Listener, Interrupt};
- use comm::{GenericPort, Peekable};
-
- // kill is only available on Unixes
- #[cfg(unix)]
- fn sigint() {
- unsafe {
- libc::funcs::posix88::signal::kill(libc::getpid(), libc::SIGINT);
- }
- }
-
- #[test] #[cfg(unix, not(target_os="android"))] // FIXME(#10378)
- fn test_io_signal_smoketest() {
- let mut signal = Listener::new();
- signal.register(Interrupt);
- sigint();
- timer::sleep(10);
- match signal.port.recv() {
- Interrupt => (),
- s => fail!("Expected Interrupt, got {:?}", s),
- }
- }
-
- #[test] #[cfg(unix, not(target_os="android"))] // FIXME(#10378)
- fn test_io_signal_two_signal_one_signum() {
- let mut s1 = Listener::new();
- let mut s2 = Listener::new();
- s1.register(Interrupt);
- s2.register(Interrupt);
- sigint();
- timer::sleep(10);
- match s1.port.recv() {
- Interrupt => (),
- s => fail!("Expected Interrupt, got {:?}", s),
- }
- match s2.port.recv() {
- Interrupt => (),
- s => fail!("Expected Interrupt, got {:?}", s),
- }
- }
-
- #[test] #[cfg(unix, not(target_os="android"))] // FIXME(#10378)
- fn test_io_signal_unregister() {
- let mut s1 = Listener::new();
- let mut s2 = Listener::new();
- s1.register(Interrupt);
- s2.register(Interrupt);
- s2.unregister(Interrupt);
- sigint();
- timer::sleep(10);
- if s2.port.peek() {
- fail!("Unexpected {:?}", s2.port.recv());
- }
- }
-
- #[cfg(windows)]
- #[test]
- fn test_io_signal_invalid_signum() {
- use io;
- use super::User1;
- let mut s = Listener::new();
- let mut called = false;
- io::io_error::cond.trap(|_| {
- called = true;
- }).inside(|| {
- if s.register(User1) {
- fail!("Unexpected successful registry of signum {:?}", User1);
- }
- });
- assert!(called);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-This modules provides bindings to the local event loop's TTY interface, using it
-to have synchronous, but non-blocking versions of stdio. These handles can be
-inspected for information about terminal dimensions or related information
-about the stream or terminal that it is attached to.
-
-# Example
-
-```rust
-use std::io;
-
-let mut out = io::stdout();
-out.write(bytes!("Hello, world!"));
-```
-
-*/
-
-use fmt;
-use libc;
-use option::{Option, Some, None};
-use result::{Ok, Err};
-use io::buffered::LineBufferedWriter;
-use rt::rtio::{IoFactory, RtioTTY, RtioFileStream, with_local_io,
- CloseAsynchronously};
-use super::{Reader, Writer, io_error, IoError, OtherIoError,
- standard_error, EndOfFile};
-
-// And so begins the tale of acquiring a uv handle to a stdio stream on all
-// platforms in all situations. Our story begins by splitting the world into two
-// categories, windows and unix. Then one day the creators of unix said let
-// there be redirection! And henceforth there was redirection away from the
-// console for standard I/O streams.
-//
-// After this day, the world split into four factions:
-//
-// 1. Unix with stdout on a terminal.
-// 2. Unix with stdout redirected.
-// 3. Windows with stdout on a terminal.
-// 4. Windows with stdout redirected.
-//
-// Many years passed, and then one day the nation of libuv decided to unify this
-// world. After months of toiling, uv created three ideas: TTY, Pipe, File.
-// These three ideas propagated throughout the lands and the four great factions
-// decided to settle among them.
-//
-// The groups of 1, 2, and 3 all worked very hard towards the idea of TTY. Upon
-// doing so, they even enhanced themselves further then their Pipe/File
-// brethren, becoming the dominant powers.
-//
-// The group of 4, however, decided to work independently. They abandoned the
-// common TTY belief throughout, and even abandoned the fledgling Pipe belief.
-// The members of the 4th faction decided to only align themselves with File.
-//
-// tl;dr; TTY works on everything but when windows stdout is redirected, in that
-// case pipe also doesn't work, but magically file does!
-enum StdSource {
- TTY(~RtioTTY),
- File(~RtioFileStream),
-}
-
-fn src<T>(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T {
- with_local_io(|io| {
- let fd = unsafe { libc::dup(fd) };
- match io.tty_open(fd, readable) {
- Ok(tty) => Some(f(TTY(tty))),
- Err(_) => {
- // It's not really that desirable if these handles are closed
- // synchronously, and because they're squirreled away in a task
- // structure the destructors will be run when the task is
- // attempted to get destroyed. This means that if we run a
- // synchronous destructor we'll attempt to do some scheduling
- // operations which will just result in sadness.
- Some(f(File(io.fs_from_raw_fd(fd, CloseAsynchronously))))
- }
- }
- }).unwrap()
-}
-
-/// Creates a new non-blocking handle to the stdin of the current process.
-///
-/// See `stdout()` for notes about this function.
-pub fn stdin() -> StdReader {
- src(libc::STDIN_FILENO, true, |src| StdReader { inner: src })
-}
-
-/// Creates a new non-blocking handle to the stdout of the current process.
-///
-/// Note that this is a fairly expensive operation in that at least one memory
-/// allocation is performed. Additionally, this must be called from a runtime
-/// task context because the stream returned will be a non-blocking object using
-/// the local scheduler to perform the I/O.
-pub fn stdout() -> StdWriter {
- src(libc::STDOUT_FILENO, false, |src| StdWriter { inner: src })
-}
-
-/// Creates a new non-blocking handle to the stderr of the current process.
-///
-/// See `stdout()` for notes about this function.
-pub fn stderr() -> StdWriter {
- src(libc::STDERR_FILENO, false, |src| StdWriter { inner: src })
-}
-
-// Helper to access the local task's stdout handle
-//
-// Note that this is not a safe function to expose because you can create an
-// aliased pointer very easily:
-//
-// with_task_stdout(|io1| {
-// with_task_stdout(|io2| {
-// // io1 aliases io2
-// })
-// })
-fn with_task_stdout(f: |&mut Writer|) {
- use rt::local::Local;
- use rt::task::Task;
-
- unsafe {
- let task: Option<*mut Task> = Local::try_unsafe_borrow();
- match task {
- Some(task) => {
- match (*task).stdout_handle {
- Some(ref mut handle) => f(*handle),
- None => {
- let handle = ~LineBufferedWriter::new(stdout());
- let mut handle = handle as ~Writer;
- f(handle);
- (*task).stdout_handle = Some(handle);
- }
- }
- }
-
- None => {
- let mut io = stdout();
- f(&mut io as &mut Writer);
- }
- }
- }
-}
-
-/// Flushes the local task's stdout handle.
-///
-/// By default, this stream is a line-buffering stream, so flushing may be
-/// necessary to ensure that all output is printed to the screen (if there are
-/// no newlines printed).
-///
-/// Note that logging macros do not use this stream. Using the logging macros
-/// will emit output to stderr, and while they are line buffered the log
-/// messages are always terminated in a newline (no need to flush).
-pub fn flush() {
- with_task_stdout(|io| io.flush())
-}
-
-/// Prints a string to the stdout of the current process. No newline is emitted
-/// after the string is printed.
-pub fn print(s: &str) {
- with_task_stdout(|io| io.write(s.as_bytes()))
-}
-
-/// Prints a string as a line. to the stdout of the current process. A literal
-/// `\n` character is printed to the console after the string.
-pub fn println(s: &str) {
- with_task_stdout(|io| {
- io.write(s.as_bytes());
- io.write(['\n' as u8]);
- })
-}
-
-/// Similar to `print`, but takes a `fmt::Arguments` structure to be compatible
-/// with the `format_args!` macro.
-pub fn print_args(fmt: &fmt::Arguments) {
- with_task_stdout(|io| fmt::write(io, fmt))
-}
-
-/// Similar to `println`, but takes a `fmt::Arguments` structure to be
-/// compatible with the `format_args!` macro.
-pub fn println_args(fmt: &fmt::Arguments) {
- with_task_stdout(|io| fmt::writeln(io, fmt))
-}
-
-/// Representation of a reader of a standard input stream
-pub struct StdReader {
- priv inner: StdSource
-}
-
-impl Reader for StdReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- let ret = match self.inner {
- TTY(ref mut tty) => tty.read(buf),
- File(ref mut file) => file.read(buf).map(|i| i as uint),
- };
- match ret {
- // When reading a piped stdin, libuv will return 0-length reads when
- // stdin reaches EOF. For pretty much all other streams it will
- // return an actual EOF error, but apparently for stdin it's a
- // little different. Hence, here we convert a 0 length read to an
- // end-of-file indicator so the caller knows to stop reading.
- Ok(0) => {
- io_error::cond.raise(standard_error(EndOfFile));
- None
- }
- Ok(amt) => Some(amt as uint),
- Err(e) => {
- io_error::cond.raise(e);
- None
- }
- }
- }
-
- fn eof(&mut self) -> bool { false }
-}
-
-/// Representation of a writer to a standard output stream
-pub struct StdWriter {
- priv inner: StdSource
-}
-
-impl StdWriter {
- /// Gets the size of this output window, if possible. This is typically used
- /// when the writer is attached to something like a terminal, this is used
- /// to fetch the dimensions of the terminal.
- ///
- /// If successful, returns Some((width, height)).
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if an error
- /// happens.
- pub fn winsize(&mut self) -> Option<(int, int)> {
- match self.inner {
- TTY(ref mut tty) => {
- match tty.get_winsize() {
- Ok(p) => Some(p),
- Err(e) => {
- io_error::cond.raise(e);
- None
- }
- }
- }
- File(..) => {
- io_error::cond.raise(IoError {
- kind: OtherIoError,
- desc: "stream is not a tty",
- detail: None,
- });
- None
- }
- }
- }
-
- /// Controls whether this output stream is a "raw stream" or simply a normal
- /// stream.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if an error
- /// happens.
- pub fn set_raw(&mut self, raw: bool) {
- match self.inner {
- TTY(ref mut tty) => {
- match tty.set_raw(raw) {
- Ok(()) => {},
- Err(e) => io_error::cond.raise(e),
- }
- }
- File(..) => {
- io_error::cond.raise(IoError {
- kind: OtherIoError,
- desc: "stream is not a tty",
- detail: None,
- });
- }
- }
- }
-
- /// Returns whether this stream is attached to a TTY instance or not.
- pub fn isatty(&self) -> bool {
- match self.inner {
- TTY(..) => true,
- File(..) => false,
- }
- }
-}
-
-impl Writer for StdWriter {
- fn write(&mut self, buf: &[u8]) {
- let ret = match self.inner {
- TTY(ref mut tty) => tty.write(buf),
- File(ref mut file) => file.write(buf),
- };
- match ret {
- Ok(()) => {}
- Err(e) => io_error::cond.raise(e)
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use rt::test::run_in_newsched_task;
-
- #[test]
- fn smoke_uv() {
- // Just make sure we can acquire handles
- stdin();
- stdout();
- stderr();
- }
-
- #[test]
- fn smoke_native() {
- do run_in_newsched_task {
- stdin();
- stdout();
- stderr();
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Synchronous Timers
-
-This module exposes the functionality to create timers, block the current task,
-and create ports which will receive notifications after a period of time.
-
-# Example
-
-```rust
-
-use std::io::Timer;
-
-let mut timer = Timer::new().unwrap();
-timer.sleep(10); // block the task for awhile
-
-let timeout = timer.oneshot(10);
-// do some work
-timeout.recv(); // wait for the timeout to expire
-
-let periodic = timer.periodic(10);
-loop {
- periodic.recv();
- // this loop is only executed once every 10ms
-}
-
-```
-
-*/
-
-use comm::{Port, PortOne};
-use option::{Option, Some, None};
-use result::{Ok, Err};
-use io::io_error;
-use rt::rtio::{IoFactory, RtioTimer, with_local_io};
-
-pub struct Timer {
- priv obj: ~RtioTimer
-}
-
-/// Sleep the current task for `msecs` milliseconds.
-pub fn sleep(msecs: u64) {
- let mut timer = Timer::new().expect("timer::sleep: could not create a Timer");
-
- timer.sleep(msecs)
-}
-
-impl Timer {
- /// Creates a new timer which can be used to put the current task to sleep
- /// for a number of milliseconds, or to possibly create channels which will
- /// get notified after an amount of time has passed.
- pub fn new() -> Option<Timer> {
- with_local_io(|io| {
- match io.timer_init() {
- Ok(t) => Some(Timer { obj: t }),
- Err(ioerr) => {
- debug!("Timer::init: failed to init: {:?}", ioerr);
- io_error::cond.raise(ioerr);
- None
- }
- }
-
- })
- }
-
- /// Blocks the current task for `msecs` milliseconds.
- ///
- /// Note that this function will cause any other ports for this timer to be
- /// invalidated (the other end will be closed).
- pub fn sleep(&mut self, msecs: u64) {
- self.obj.sleep(msecs);
- }
-
- /// Creates a oneshot port which will have a notification sent when `msecs`
- /// milliseconds has elapsed. This does *not* block the current task, but
- /// instead returns immediately.
- ///
- /// Note that this invalidates any previous port which has been created by
- /// this timer, and that the returned port will be invalidated once the
- /// timer is destroyed (when it falls out of scope).
- pub fn oneshot(&mut self, msecs: u64) -> PortOne<()> {
- self.obj.oneshot(msecs)
- }
-
- /// Creates a port which will have a continuous stream of notifications
- /// being sent every `msecs` milliseconds. This does *not* block the
- /// current task, but instead returns immediately. The first notification
- /// will not be received immediately, but rather after `msec` milliseconds
- /// have passed.
- ///
- /// Note that this invalidates any previous port which has been created by
- /// this timer, and that the returned port will be invalidated once the
- /// timer is destroyed (when it falls out of scope).
- pub fn periodic(&mut self, msecs: u64) -> Port<()> {
- self.obj.period(msecs)
- }
-}
-
-#[cfg(test)]
-mod test {
- use prelude::*;
- use super::*;
- use rt::test::*;
-
- #[test]
- fn test_io_timer_sleep_simple() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- timer.sleep(1);
- }
- }
-
- #[test]
- fn test_io_timer_sleep_oneshot() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- timer.oneshot(1).recv();
- }
- }
-
- #[test]
- fn test_io_timer_sleep_oneshot_forget() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- timer.oneshot(100000000000);
- }
- }
-
- #[test]
- fn oneshot_twice() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- let port1 = timer.oneshot(10000);
- let port = timer.oneshot(1);
- port.recv();
- assert_eq!(port1.try_recv(), None);
- }
- }
-
- #[test]
- fn test_io_timer_oneshot_then_sleep() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- let port = timer.oneshot(100000000000);
- timer.sleep(1); // this should invalidate the port
-
- assert_eq!(port.try_recv(), None);
- }
- }
-
- #[test]
- fn test_io_timer_sleep_periodic() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- let port = timer.periodic(1);
- port.recv();
- port.recv();
- port.recv();
- }
- }
-
- #[test]
- fn test_io_timer_sleep_periodic_forget() {
- do run_in_mt_newsched_task {
- let mut timer = Timer::new().unwrap();
- timer.periodic(100000000000);
- }
- }
-
- #[test]
- fn test_io_timer_sleep_standalone() {
- do run_in_mt_newsched_task {
- sleep(1)
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Composable external iterators
-
-# The `Iterator` trait
-
-This module defines Rust's core iteration trait. The `Iterator` trait has one
-un-implemented method, `next`. All other methods are derived through default
-methods to perform operations such as `zip`, `chain`, `enumerate`, and `fold`.
-
-The goal of this module is to unify iteration across all containers in Rust.
-An iterator can be considered as a state machine which is used to track which
-element will be yielded next.
-
-There are various extensions also defined in this module to assist with various
-types of iteration, such as the `DoubleEndedIterator` for iterating in reverse,
-the `FromIterator` trait for creating a container from an iterator, and much
-more.
-
-## Rust's `for` loop
-
-The special syntax used by rust's `for` loop is based around the `Iterator`
-trait defined in this module. For loops can be viewed as a syntactical expansion
-into a `loop`, for example, the `for` loop in this example is essentially
-translated to the `loop` below.
-
-```rust
-let values = ~[1, 2, 3];
-
-// "Syntactical sugar" taking advantage of an iterator
-for &x in values.iter() {
- println!("{}", x);
-}
-
-// Rough translation of the iteration without a `for` iterator.
-let mut it = values.iter();
-loop {
- match it.next() {
- Some(&x) => {
- println!("{}", x);
- }
- None => { break }
- }
-}
- ```
-
-This `for` loop syntax can be applied to any iterator over any type.
-
-## Iteration protocol and more
-
-More detailed information about iterators can be found in the [container
-tutorial](http://static.rust-lang.org/doc/master/tutorial-container.html) with
-the rest of the rust manuals.
-
-*/
-
-use cmp;
-use num::{Zero, One, Integer, CheckedAdd, CheckedSub, Saturating, ToPrimitive};
-use option::{Option, Some, None};
-use ops::{Add, Mul, Sub};
-use cmp::{Eq, Ord};
-use clone::Clone;
-use uint;
-use util;
-
-/// Conversion from an `Iterator`
-pub trait FromIterator<A> {
- /// Build a container with elements from an external iterator.
- fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> Self;
-}
-
-/// A type growable from an `Iterator` implementation
-pub trait Extendable<A>: FromIterator<A> {
- /// Extend a container with the elements yielded by an iterator
- fn extend<T: Iterator<A>>(&mut self, iterator: &mut T);
-}
-
-/// An interface for dealing with "external iterators". These types of iterators
-/// can be resumed at any time as all state is stored internally as opposed to
-/// being located on the call stack.
-///
-/// The Iterator protocol states that an iterator yields a (potentially-empty,
-/// potentially-infinite) sequence of values, and returns `None` to signal that
-/// it's finished. The Iterator protocol does not define behavior after `None`
-/// is returned. A concrete Iterator implementation may choose to behave however
-/// it wishes, either by returning `None` infinitely, or by doing something
-/// else.
-pub trait Iterator<A> {
- /// Advance the iterator and return the next value. Return `None` when the end is reached.
- fn next(&mut self) -> Option<A>;
-
- /// Return a lower bound and upper bound on the remaining length of the iterator.
- ///
- /// The common use case for the estimate is pre-allocating space to store the results.
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) { (0, None) }
-
- /// Chain this iterator with another, returning a new iterator which will
- /// finish iterating over the current iterator, and then it will iterate
- /// over the other specified iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [0];
- /// let b = [1];
- /// let mut it = a.iter().chain(b.iter());
- /// assert_eq!(it.next().unwrap(), &0);
- /// assert_eq!(it.next().unwrap(), &1);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn chain<U: Iterator<A>>(self, other: U) -> Chain<Self, U> {
- Chain{a: self, b: other, flag: false}
- }
-
- /// Creates an iterator which iterates over both this and the specified
- /// iterators simultaneously, yielding the two elements as pairs. When
- /// either iterator returns None, all further invocations of next() will
- /// return None.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [0];
- /// let b = [1];
- /// let mut it = a.iter().zip(b.iter());
- /// assert_eq!(it.next().unwrap(), (&0, &1));
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn zip<B, U: Iterator<B>>(self, other: U) -> Zip<Self, U> {
- Zip{a: self, b: other}
- }
-
- /// Creates a new iterator which will apply the specified function to each
- /// element returned by the first, yielding the mapped element instead.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2];
- /// let mut it = a.iter().map(|&x| 2 * x);
- /// assert_eq!(it.next().unwrap(), 2);
- /// assert_eq!(it.next().unwrap(), 4);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn map<'r, B>(self, f: 'r |A| -> B) -> Map<'r, A, B, Self> {
- Map{iter: self, f: f}
- }
-
- /// Creates an iterator which applies the predicate to each element returned
- /// by this iterator. Only elements which have the predicate evaluate to
- /// `true` will be yielded.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2];
- /// let mut it = a.iter().filter(|&x| *x > 1);
- /// assert_eq!(it.next().unwrap(), &2);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn filter<'r>(self, predicate: 'r |&A| -> bool) -> Filter<'r, A, Self> {
- Filter{iter: self, predicate: predicate}
- }
-
- /// Creates an iterator which both filters and maps elements.
- /// If the specified function returns None, the element is skipped.
- /// Otherwise the option is unwrapped and the new value is yielded.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2];
- /// let mut it = a.iter().filter_map(|&x| if x > 1 {Some(2 * x)} else {None});
- /// assert_eq!(it.next().unwrap(), 4);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn filter_map<'r, B>(self, f: 'r |A| -> Option<B>) -> FilterMap<'r, A, B, Self> {
- FilterMap { iter: self, f: f }
- }
-
- /// Creates an iterator which yields a pair of the value returned by this
- /// iterator plus the current index of iteration.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [100, 200];
- /// let mut it = a.iter().enumerate();
- /// assert_eq!(it.next().unwrap(), (0, &100));
- /// assert_eq!(it.next().unwrap(), (1, &200));
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn enumerate(self) -> Enumerate<Self> {
- Enumerate{iter: self, count: 0}
- }
-
-
- /// Creates an iterator that has a `.peek()` method
- /// that returns a optional reference to the next element.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [100, 200, 300];
- /// let mut it = xs.iter().map(|&x|x).peekable();
- /// assert_eq!(it.peek().unwrap(), &100);
- /// assert_eq!(it.next().unwrap(), 100);
- /// assert_eq!(it.next().unwrap(), 200);
- /// assert_eq!(it.peek().unwrap(), &300);
- /// assert_eq!(it.peek().unwrap(), &300);
- /// assert_eq!(it.next().unwrap(), 300);
- /// assert!(it.peek().is_none());
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn peekable(self) -> Peekable<A, Self> {
- Peekable{iter: self, peeked: None}
- }
-
- /// Creates an iterator which invokes the predicate on elements until it
- /// returns false. Once the predicate returns false, all further elements are
- /// yielded.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 2, 1];
- /// let mut it = a.iter().skip_while(|&a| *a < 3);
- /// assert_eq!(it.next().unwrap(), &3);
- /// assert_eq!(it.next().unwrap(), &2);
- /// assert_eq!(it.next().unwrap(), &1);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn skip_while<'r>(self, predicate: 'r |&A| -> bool) -> SkipWhile<'r, A, Self> {
- SkipWhile{iter: self, flag: false, predicate: predicate}
- }
-
- /// Creates an iterator which yields elements so long as the predicate
- /// returns true. After the predicate returns false for the first time, no
- /// further elements will be yielded.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 2, 1];
- /// let mut it = a.iter().take_while(|&a| *a < 3);
- /// assert_eq!(it.next().unwrap(), &1);
- /// assert_eq!(it.next().unwrap(), &2);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn take_while<'r>(self, predicate: 'r |&A| -> bool) -> TakeWhile<'r, A, Self> {
- TakeWhile{iter: self, flag: false, predicate: predicate}
- }
-
- /// Creates an iterator which skips the first `n` elements of this iterator,
- /// and then it yields all further items.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter().skip(3);
- /// assert_eq!(it.next().unwrap(), &4);
- /// assert_eq!(it.next().unwrap(), &5);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn skip(self, n: uint) -> Skip<Self> {
- Skip{iter: self, n: n}
- }
-
- /// Creates an iterator which yields the first `n` elements of this
- /// iterator, and then it will always return None.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter().take(3);
- /// assert_eq!(it.next().unwrap(), &1);
- /// assert_eq!(it.next().unwrap(), &2);
- /// assert_eq!(it.next().unwrap(), &3);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn take(self, n: uint) -> Take<Self> {
- Take{iter: self, n: n}
- }
-
- /// Creates a new iterator which behaves in a similar fashion to foldl.
- /// There is a state which is passed between each iteration and can be
- /// mutated as necessary. The yielded values from the closure are yielded
- /// from the Scan instance when not None.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter().scan(1, |fac, &x| {
- /// *fac = *fac * x;
- /// Some(*fac)
- /// });
- /// assert_eq!(it.next().unwrap(), 1);
- /// assert_eq!(it.next().unwrap(), 2);
- /// assert_eq!(it.next().unwrap(), 6);
- /// assert_eq!(it.next().unwrap(), 24);
- /// assert_eq!(it.next().unwrap(), 120);
- /// assert!(it.next().is_none());
- /// ```
- #[inline]
- fn scan<'r, St, B>(self, initial_state: St, f: 'r |&mut St, A| -> Option<B>)
- -> Scan<'r, A, B, Self, St> {
- Scan{iter: self, f: f, state: initial_state}
- }
-
- /// Creates an iterator that maps each element to an iterator,
- /// and yields the elements of the produced iterators
- ///
- /// # Example
- ///
- /// ```rust
- /// let xs = [2u, 3];
- /// let ys = [0u, 1, 0, 1, 2];
- /// let mut it = xs.iter().flat_map(|&x| count(0u, 1).take(x));
- /// // Check that `it` has the same elements as `ys`
- /// let mut i = 0;
- /// for x: uint in it {
- /// assert_eq!(x, ys[i]);
- /// i += 1;
- /// }
- /// ```
- #[inline]
- fn flat_map<'r, B, U: Iterator<B>>(self, f: 'r |A| -> U)
- -> FlatMap<'r, A, Self, U> {
- FlatMap{iter: self, f: f, frontiter: None, backiter: None }
- }
-
- /// Creates an iterator that yields `None` forever after the underlying
- /// iterator yields `None`. Random-access iterator behavior is not
- /// affected, only single and double-ended iterator behavior.
- ///
- /// # Example
- ///
- /// ```rust
- /// fn process<U: Iterator<int>>(it: U) -> int {
- /// let mut it = it.fuse();
- /// let mut sum = 0;
- /// for x in it {
- /// if x > 5 {
- /// break;
- /// }
- /// sum += x;
- /// }
- /// // did we exhaust the iterator?
- /// if it.next().is_none() {
- /// sum += 1000;
- /// }
- /// sum
- /// }
- /// let x = ~[1,2,3,7,8,9];
- /// assert_eq!(process(x.move_iter()), 1006);
- /// ```
- #[inline]
- fn fuse(self) -> Fuse<Self> {
- Fuse{iter: self, done: false}
- }
-
- /// Creates an iterator that calls a function with a reference to each
- /// element before yielding it. This is often useful for debugging an
- /// iterator pipeline.
- ///
- /// # Example
- ///
- /// ```rust
- ///let xs = [1u, 4, 2, 3, 8, 9, 6];
- ///let sum = xs.iter()
- /// .map(|&x| x)
- /// .inspect(|&x| debug!("filtering %u", x))
- /// .filter(|&x| x % 2 == 0)
- /// .inspect(|&x| debug!("%u made it through", x))
- /// .sum();
- ///println(sum.to_str());
- /// ```
- #[inline]
- fn inspect<'r>(self, f: 'r |&A|) -> Inspect<'r, A, Self> {
- Inspect{iter: self, f: f}
- }
-
- /// Creates a wrapper around a mutable reference to the iterator.
- ///
- /// This is useful to allow applying iterator adaptors while still
- /// retaining ownership of the original iterator value.
- ///
- /// # Example
- ///
- /// ```rust
- /// let mut xs = range(0, 10);
- /// // sum the first five values
- /// let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
- /// assert!(partial_sum == 10);
- /// // xs.next() is now `5`
- /// assert!(xs.next() == Some(5));
- /// ```
- fn by_ref<'r>(&'r mut self) -> ByRef<'r, Self> {
- ByRef{iter: self}
- }
-
- /// Apply a function to each element, or stop iterating if the
- /// function returns `false`.
- ///
- /// # Example
- ///
- /// ```rust
- /// range(0, 5).advance(|x| {print!("{} ", x); true});
- /// ```
- #[inline]
- fn advance(&mut self, f: |A| -> bool) -> bool {
- loop {
- match self.next() {
- Some(x) => {
- if !f(x) { return false; }
- }
- None => { return true; }
- }
- }
- }
-
- /// Loops through the entire iterator, collecting all of the elements into
- /// a container implementing `FromIterator`.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let b: ~[int] = a.iter().map(|&x| x).collect();
- /// assert!(a == b);
- /// ```
- #[inline]
- fn collect<B: FromIterator<A>>(&mut self) -> B {
- FromIterator::from_iterator(self)
- }
-
- /// Loops through the entire iterator, collecting all of the elements into
- /// a unique vector. This is simply collect() specialized for vectors.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let b: ~[int] = a.iter().map(|&x| x).to_owned_vec();
- /// assert!(a == b);
- /// ```
- #[inline]
- fn to_owned_vec(&mut self) -> ~[A] {
- self.collect()
- }
-
- /// Loops through `n` iterations, returning the `n`th element of the
- /// iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter();
- /// assert!(it.nth(2).unwrap() == &3);
- /// assert!(it.nth(2) == None);
- /// ```
- #[inline]
- fn nth(&mut self, mut n: uint) -> Option<A> {
- loop {
- match self.next() {
- Some(x) => if n == 0 { return Some(x) },
- None => return None
- }
- n -= 1;
- }
- }
-
- /// Loops through the entire iterator, returning the last element of the
- /// iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// assert!(a.iter().last().unwrap() == &5);
- /// ```
- #[inline]
- fn last(&mut self) -> Option<A> {
- let mut last = None;
- for x in *self { last = Some(x); }
- last
- }
-
- /// Performs a fold operation over the entire iterator, returning the
- /// eventual state at the end of the iteration.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// assert!(a.iter().fold(0, |a, &b| a + b) == 15);
- /// ```
- #[inline]
- fn fold<B>(&mut self, init: B, f: |B, A| -> B) -> B {
- let mut accum = init;
- loop {
- match self.next() {
- Some(x) => { accum = f(accum, x); }
- None => { break; }
- }
- }
- accum
- }
-
- /// Counts the number of elements in this iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter();
- /// assert!(it.len() == 5);
- /// assert!(it.len() == 0);
- /// ```
- #[inline]
- fn len(&mut self) -> uint {
- self.fold(0, |cnt, _x| cnt + 1)
- }
-
- /// Tests whether the predicate holds true for all elements in the iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// assert!(a.iter().all(|&x| *x > 0));
- /// assert!(!a.iter().all(|&x| *x > 2));
- /// ```
- #[inline]
- fn all(&mut self, f: |A| -> bool) -> bool {
- for x in *self { if !f(x) { return false; } }
- true
- }
-
- /// Tests whether any element of an iterator satisfies the specified
- /// predicate.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter();
- /// assert!(it.any(|&x| *x == 3));
- /// assert!(!it.any(|&x| *x == 3));
- /// ```
- #[inline]
- fn any(&mut self, f: |A| -> bool) -> bool {
- for x in *self { if f(x) { return true; } }
- false
- }
-
- /// Return the first element satisfying the specified predicate
- #[inline]
- fn find(&mut self, predicate: |&A| -> bool) -> Option<A> {
- for x in *self {
- if predicate(&x) { return Some(x) }
- }
- None
- }
-
- /// Return the index of the first element satisfying the specified predicate
- #[inline]
- fn position(&mut self, predicate: |A| -> bool) -> Option<uint> {
- let mut i = 0;
- for x in *self {
- if predicate(x) {
- return Some(i);
- }
- i += 1;
- }
- None
- }
-
- /// Count the number of elements satisfying the specified predicate
- #[inline]
- fn count(&mut self, predicate: |A| -> bool) -> uint {
- let mut i = 0;
- for x in *self {
- if predicate(x) { i += 1 }
- }
- i
- }
-
- /// Return the element that gives the maximum value from the
- /// specified function.
- ///
- /// # Example
- ///
- /// ```rust
- /// let xs = [-3, 0, 1, 5, -10];
- /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
- /// ```
- #[inline]
- fn max_by<B: Ord>(&mut self, f: |&A| -> B) -> Option<A> {
- self.fold(None, |max: Option<(A, B)>, x| {
- let x_val = f(&x);
- match max {
- None => Some((x, x_val)),
- Some((y, y_val)) => if x_val > y_val {
- Some((x, x_val))
- } else {
- Some((y, y_val))
- }
- }
- }).map(|(x, _)| x)
- }
-
- /// Return the element that gives the minimum value from the
- /// specified function.
- ///
- /// # Example
- ///
- /// ```rust
- /// let xs = [-3, 0, 1, 5, -10];
- /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
- /// ```
- #[inline]
- fn min_by<B: Ord>(&mut self, f: |&A| -> B) -> Option<A> {
- self.fold(None, |min: Option<(A, B)>, x| {
- let x_val = f(&x);
- match min {
- None => Some((x, x_val)),
- Some((y, y_val)) => if x_val < y_val {
- Some((x, x_val))
- } else {
- Some((y, y_val))
- }
- }
- }).map(|(x, _)| x)
- }
-}
-
-/// A range iterator able to yield elements from both ends
-pub trait DoubleEndedIterator<A>: Iterator<A> {
- /// Yield an element from the end of the range, returning `None` if the range is empty.
- fn next_back(&mut self) -> Option<A>;
-
- /// Flip the direction of the iterator
- ///
- /// The inverted iterator flips the ends on an iterator that can already
- /// be iterated from the front and from the back.
- ///
- ///
- /// If the iterator also implements RandomAccessIterator, the inverted
- /// iterator is also random access, with the indices starting at the back
- /// of the original iterator.
- ///
- /// Note: Random access with inverted indices still only applies to the first
- /// `uint::max_value` elements of the original iterator.
- #[inline]
- fn invert(self) -> Invert<Self> {
- Invert{iter: self}
- }
-}
-
-/// A double-ended iterator yielding mutable references
-pub trait MutableDoubleEndedIterator {
- // FIXME: #5898: should be called `reverse`
- /// Use an iterator to reverse a container in-place
- fn reverse_(&mut self);
-}
-
-impl<'self, A, T: DoubleEndedIterator<&'self mut A>> MutableDoubleEndedIterator for T {
- // FIXME: #5898: should be called `reverse`
- /// Use an iterator to reverse a container in-place
- fn reverse_(&mut self) {
- loop {
- match (self.next(), self.next_back()) {
- (Some(x), Some(y)) => util::swap(x, y),
- _ => break
- }
- }
- }
-}
-
-
-/// An object implementing random access indexing by `uint`
-///
-/// A `RandomAccessIterator` should be either infinite or a `DoubleEndedIterator`.
-pub trait RandomAccessIterator<A>: Iterator<A> {
- /// Return the number of indexable elements. At most `std::uint::max_value`
- /// elements are indexable, even if the iterator represents a longer range.
- fn indexable(&self) -> uint;
-
- /// Return an element at an index
- fn idx(&self, index: uint) -> Option<A>;
-}
-
-/// An iterator that knows its exact length
-///
-/// This trait is a helper for iterators like the vector iterator, so that
-/// it can support double-ended enumeration.
-///
-/// `Iterator::size_hint` *must* return the exact size of the iterator.
-/// Note that the size must fit in `uint`.
-pub trait ExactSize<A> : DoubleEndedIterator<A> {
- /// Return the index of the last element satisfying the specified predicate
- ///
- /// If no element matches, None is returned.
- #[inline]
- fn rposition(&mut self, predicate: |A| -> bool) -> Option<uint> {
- let (lower, upper) = self.size_hint();
- assert!(upper == Some(lower));
- let mut i = lower;
- loop {
- match self.next_back() {
- None => break,
- Some(x) => {
- i = match i.checked_sub(&1) {
- Some(x) => x,
- None => fail!("rposition: incorrect ExactSize")
- };
- if predicate(x) {
- return Some(i)
- }
- }
- }
- }
- None
- }
-}
-
-// All adaptors that preserve the size of the wrapped iterator are fine
-// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`.
-impl<A, T: ExactSize<A>> ExactSize<(uint, A)> for Enumerate<T> {}
-impl<'self, A, T: ExactSize<A>> ExactSize<A> for Inspect<'self, A, T> {}
-impl<A, T: ExactSize<A>> ExactSize<A> for Invert<T> {}
-impl<'self, A, B, T: ExactSize<A>> ExactSize<B> for Map<'self, A, B, T> {}
-impl<A, B, T: ExactSize<A>, U: ExactSize<B>> ExactSize<(A, B)> for Zip<T, U> {}
-
-/// An double-ended iterator with the direction inverted
-#[deriving(Clone)]
-pub struct Invert<T> {
- priv iter: T
-}
-
-impl<A, T: DoubleEndedIterator<A>> Iterator<A> for Invert<T> {
- #[inline]
- fn next(&mut self) -> Option<A> { self.iter.next_back() }
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
-}
-
-impl<A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Invert<T> {
- #[inline]
- fn next_back(&mut self) -> Option<A> { self.iter.next() }
-}
-
-impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterator<A>
- for Invert<T> {
- #[inline]
- fn indexable(&self) -> uint { self.iter.indexable() }
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- self.iter.idx(self.indexable() - index - 1)
- }
-}
-
-/// A mutable reference to an iterator
-pub struct ByRef<'self, T> {
- priv iter: &'self mut T
-}
-
-impl<'self, A, T: Iterator<A>> Iterator<A> for ByRef<'self, T> {
- #[inline]
- fn next(&mut self) -> Option<A> { self.iter.next() }
- // FIXME: #9629 we cannot implement &self methods like size_hint on ByRef
-}
-
-impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for ByRef<'self, T> {
- #[inline]
- fn next_back(&mut self) -> Option<A> { self.iter.next_back() }
-}
-
-/// A trait for iterators over elements which can be added together
-pub trait AdditiveIterator<A> {
- /// Iterates over the entire iterator, summing up all the elements
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// let mut it = a.iter().map(|&x| x);
- /// assert!(it.sum() == 15);
- /// ```
- fn sum(&mut self) -> A;
-}
-
-impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
- #[inline]
- fn sum(&mut self) -> A {
- let zero: A = Zero::zero();
- self.fold(zero, |s, x| s + x)
- }
-}
-
-/// A trait for iterators over elements whose elements can be multiplied
-/// together.
-pub trait MultiplicativeIterator<A> {
- /// Iterates over the entire iterator, multiplying all the elements
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::iter::count;
- ///
- /// fn factorial(n: uint) -> uint {
- /// count(1u, 1).take_while(|&i| i <= n).product()
- /// }
- /// assert!(factorial(0) == 1);
- /// assert!(factorial(1) == 1);
- /// assert!(factorial(5) == 120);
- /// ```
- fn product(&mut self) -> A;
-}
-
-impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
- #[inline]
- fn product(&mut self) -> A {
- let one: A = One::one();
- self.fold(one, |p, x| p * x)
- }
-}
-
-/// A trait for iterators over elements which can be compared to one another.
-/// The type of each element must ascribe to the `Ord` trait.
-pub trait OrdIterator<A> {
- /// Consumes the entire iterator to return the maximum element.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// assert!(a.iter().max().unwrap() == &5);
- /// ```
- fn max(&mut self) -> Option<A>;
-
- /// Consumes the entire iterator to return the minimum element.
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = [1, 2, 3, 4, 5];
- /// assert!(a.iter().min().unwrap() == &1);
- /// ```
- fn min(&mut self) -> Option<A>;
-}
-
-impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
- #[inline]
- fn max(&mut self) -> Option<A> {
- self.fold(None, |max, x| {
- match max {
- None => Some(x),
- Some(y) => Some(cmp::max(x, y))
- }
- })
- }
-
- #[inline]
- fn min(&mut self) -> Option<A> {
- self.fold(None, |min, x| {
- match min {
- None => Some(x),
- Some(y) => Some(cmp::min(x, y))
- }
- })
- }
-}
-
-/// A trait for iterators that are clonable.
-pub trait ClonableIterator {
- /// Repeats an iterator endlessly
- ///
- /// # Example
- ///
- /// ```rust
- /// let a = count(1,1).take(1);
- /// let mut cy = a.cycle();
- /// assert_eq!(cy.next(), Some(1));
- /// assert_eq!(cy.next(), Some(1));
- /// ```
- fn cycle(self) -> Cycle<Self>;
-}
-
-impl<A, T: Clone + Iterator<A>> ClonableIterator for T {
- #[inline]
- fn cycle(self) -> Cycle<T> {
- Cycle{orig: self.clone(), iter: self}
- }
-}
-
-/// An iterator that repeats endlessly
-#[deriving(Clone)]
-pub struct Cycle<T> {
- priv orig: T,
- priv iter: T,
-}
-
-impl<A, T: Clone + Iterator<A>> Iterator<A> for Cycle<T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- match self.iter.next() {
- None => { self.iter = self.orig.clone(); self.iter.next() }
- y => y
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- // the cycle iterator is either empty or infinite
- match self.orig.size_hint() {
- sz @ (0, Some(0)) => sz,
- (0, _) => (0, None),
- _ => (uint::max_value, None)
- }
- }
-}
-
-impl<A, T: Clone + RandomAccessIterator<A>> RandomAccessIterator<A> for Cycle<T> {
- #[inline]
- fn indexable(&self) -> uint {
- if self.orig.indexable() > 0 {
- uint::max_value
- } else {
- 0
- }
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- let liter = self.iter.indexable();
- let lorig = self.orig.indexable();
- if lorig == 0 {
- None
- } else if index < liter {
- self.iter.idx(index)
- } else {
- self.orig.idx((index - liter) % lorig)
- }
- }
-}
-
-/// An iterator which strings two iterators together
-#[deriving(Clone)]
-pub struct Chain<T, U> {
- priv a: T,
- priv b: U,
- priv flag: bool
-}
-
-impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for Chain<T, U> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.flag {
- self.b.next()
- } else {
- match self.a.next() {
- Some(x) => return Some(x),
- _ => ()
- }
- self.flag = true;
- self.b.next()
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (a_lower, a_upper) = self.a.size_hint();
- let (b_lower, b_upper) = self.b.size_hint();
-
- let lower = a_lower.saturating_add(b_lower);
-
- let upper = match (a_upper, b_upper) {
- (Some(x), Some(y)) => x.checked_add(&y),
- _ => None
- };
-
- (lower, upper)
- }
-}
-
-impl<A, T: DoubleEndedIterator<A>, U: DoubleEndedIterator<A>> DoubleEndedIterator<A>
-for Chain<T, U> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- match self.b.next_back() {
- Some(x) => Some(x),
- None => self.a.next_back()
- }
- }
-}
-
-impl<A, T: RandomAccessIterator<A>, U: RandomAccessIterator<A>> RandomAccessIterator<A>
-for Chain<T, U> {
- #[inline]
- fn indexable(&self) -> uint {
- let (a, b) = (self.a.indexable(), self.b.indexable());
- a.saturating_add(b)
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- let len = self.a.indexable();
- if index < len {
- self.a.idx(index)
- } else {
- self.b.idx(index - len)
- }
- }
-}
-
-/// An iterator which iterates two other iterators simultaneously
-#[deriving(Clone)]
-pub struct Zip<T, U> {
- priv a: T,
- priv b: U
-}
-
-impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for Zip<T, U> {
- #[inline]
- fn next(&mut self) -> Option<(A, B)> {
- match self.a.next() {
- None => None,
- Some(x) => match self.b.next() {
- None => None,
- Some(y) => Some((x, y))
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (a_lower, a_upper) = self.a.size_hint();
- let (b_lower, b_upper) = self.b.size_hint();
-
- let lower = cmp::min(a_lower, b_lower);
-
- let upper = match (a_upper, b_upper) {
- (Some(x), Some(y)) => Some(cmp::min(x,y)),
- (Some(x), None) => Some(x),
- (None, Some(y)) => Some(y),
- (None, None) => None
- };
-
- (lower, upper)
- }
-}
-
-impl<A, B, T: ExactSize<A>, U: ExactSize<B>> DoubleEndedIterator<(A, B)>
-for Zip<T, U> {
- #[inline]
- fn next_back(&mut self) -> Option<(A, B)> {
- let (a_sz, a_upper) = self.a.size_hint();
- let (b_sz, b_upper) = self.b.size_hint();
- assert!(a_upper == Some(a_sz));
- assert!(b_upper == Some(b_sz));
- if a_sz < b_sz {
- for _ in range(0, b_sz - a_sz) { self.b.next_back(); }
- } else if a_sz > b_sz {
- for _ in range(0, a_sz - b_sz) { self.a.next_back(); }
- }
- let (a_sz, _) = self.a.size_hint();
- let (b_sz, _) = self.b.size_hint();
- assert!(a_sz == b_sz);
- match (self.a.next_back(), self.b.next_back()) {
- (Some(x), Some(y)) => Some((x, y)),
- _ => None
- }
- }
-}
-
-impl<A, B, T: RandomAccessIterator<A>, U: RandomAccessIterator<B>>
-RandomAccessIterator<(A, B)> for Zip<T, U> {
- #[inline]
- fn indexable(&self) -> uint {
- cmp::min(self.a.indexable(), self.b.indexable())
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<(A, B)> {
- match self.a.idx(index) {
- None => None,
- Some(x) => match self.b.idx(index) {
- None => None,
- Some(y) => Some((x, y))
- }
- }
- }
-}
-
-/// An iterator which maps the values of `iter` with `f`
-pub struct Map<'self, A, B, T> {
- priv iter: T,
- priv f: 'self |A| -> B
-}
-
-impl<'self, A, B, T> Map<'self, A, B, T> {
- #[inline]
- fn do_map(&self, elt: Option<A>) -> Option<B> {
- match elt {
- Some(a) => Some((self.f)(a)),
- _ => None
- }
- }
-}
-
-impl<'self, A, B, T: Iterator<A>> Iterator<B> for Map<'self, A, B, T> {
- #[inline]
- fn next(&mut self) -> Option<B> {
- let next = self.iter.next();
- self.do_map(next)
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'self, A, B, T> {
- #[inline]
- fn next_back(&mut self) -> Option<B> {
- let next = self.iter.next_back();
- self.do_map(next)
- }
-}
-
-impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'self, A, B, T> {
- #[inline]
- fn indexable(&self) -> uint {
- self.iter.indexable()
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<B> {
- self.do_map(self.iter.idx(index))
- }
-}
-
-/// An iterator which filters the elements of `iter` with `predicate`
-pub struct Filter<'self, A, T> {
- priv iter: T,
- priv predicate: 'self |&A| -> bool
-}
-
-impl<'self, A, T: Iterator<A>> Iterator<A> for Filter<'self, A, T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- for x in self.iter {
- if (self.predicate)(&x) {
- return Some(x);
- } else {
- continue
- }
- }
- None
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-}
-
-impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'self, A, T> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- loop {
- match self.iter.next_back() {
- None => return None,
- Some(x) => {
- if (self.predicate)(&x) {
- return Some(x);
- } else {
- continue
- }
- }
- }
- }
- }
-}
-
-/// An iterator which uses `f` to both filter and map elements from `iter`
-pub struct FilterMap<'self, A, B, T> {
- priv iter: T,
- priv f: 'self |A| -> Option<B>
-}
-
-impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'self, A, B, T> {
- #[inline]
- fn next(&mut self) -> Option<B> {
- for x in self.iter {
- match (self.f)(x) {
- Some(y) => return Some(y),
- None => ()
- }
- }
- None
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-}
-
-impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
-for FilterMap<'self, A, B, T> {
- #[inline]
- fn next_back(&mut self) -> Option<B> {
- loop {
- match self.iter.next_back() {
- None => return None,
- Some(x) => {
- match (self.f)(x) {
- Some(y) => return Some(y),
- None => ()
- }
- }
- }
- }
- }
-}
-
-/// An iterator which yields the current count and the element during iteration
-#[deriving(Clone)]
-pub struct Enumerate<T> {
- priv iter: T,
- priv count: uint
-}
-
-impl<A, T: Iterator<A>> Iterator<(uint, A)> for Enumerate<T> {
- #[inline]
- fn next(&mut self) -> Option<(uint, A)> {
- match self.iter.next() {
- Some(a) => {
- let ret = Some((self.count, a));
- self.count += 1;
- ret
- }
- _ => None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-impl<A, T: ExactSize<A>> DoubleEndedIterator<(uint, A)> for Enumerate<T> {
- #[inline]
- fn next_back(&mut self) -> Option<(uint, A)> {
- match self.iter.next_back() {
- Some(a) => {
- let (lower, upper) = self.iter.size_hint();
- assert!(upper == Some(lower));
- Some((self.count + lower, a))
- }
- _ => None
- }
- }
-}
-
-impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerate<T> {
- #[inline]
- fn indexable(&self) -> uint {
- self.iter.indexable()
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<(uint, A)> {
- match self.iter.idx(index) {
- Some(a) => Some((self.count + index, a)),
- _ => None,
- }
- }
-}
-
-/// An iterator with a `peek()` that returns an optional reference to the next element.
-pub struct Peekable<A, T> {
- priv iter: T,
- priv peeked: Option<A>,
-}
-
-impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.peeked.is_some() { self.peeked.take() }
- else { self.iter.next() }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (lo, hi) = self.iter.size_hint();
- if self.peeked.is_some() {
- let lo = lo.saturating_add(1);
- let hi = match hi {
- Some(x) => x.checked_add(&1),
- None => None
- };
- (lo, hi)
- } else {
- (lo, hi)
- }
- }
-}
-
-impl<'self, A, T: Iterator<A>> Peekable<A, T> {
- /// Return a reference to the next element of the iterator with out advancing it,
- /// or None if the iterator is exhausted.
- #[inline]
- pub fn peek(&'self mut self) -> Option<&'self A> {
- if self.peeked.is_none() {
- self.peeked = self.iter.next();
- }
- match self.peeked {
- Some(ref value) => Some(value),
- None => None,
- }
- }
-}
-
-/// An iterator which rejects elements while `predicate` is true
-pub struct SkipWhile<'self, A, T> {
- priv iter: T,
- priv flag: bool,
- priv predicate: 'self |&A| -> bool
-}
-
-impl<'self, A, T: Iterator<A>> Iterator<A> for SkipWhile<'self, A, T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- let mut next = self.iter.next();
- if self.flag {
- next
- } else {
- loop {
- match next {
- Some(x) => {
- if (self.predicate)(&x) {
- next = self.iter.next();
- continue
- } else {
- self.flag = true;
- return Some(x)
- }
- }
- None => return None
- }
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-}
-
-/// An iterator which only accepts elements while `predicate` is true
-pub struct TakeWhile<'self, A, T> {
- priv iter: T,
- priv flag: bool,
- priv predicate: 'self |&A| -> bool
-}
-
-impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhile<'self, A, T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.flag {
- None
- } else {
- match self.iter.next() {
- Some(x) => {
- if (self.predicate)(&x) {
- Some(x)
- } else {
- self.flag = true;
- None
- }
- }
- None => None
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-}
-
-/// An iterator which skips over `n` elements of `iter`.
-#[deriving(Clone)]
-pub struct Skip<T> {
- priv iter: T,
- priv n: uint
-}
-
-impl<A, T: Iterator<A>> Iterator<A> for Skip<T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- let mut next = self.iter.next();
- if self.n == 0 {
- next
- } else {
- let mut n = self.n;
- while n > 0 {
- n -= 1;
- match next {
- Some(_) => {
- next = self.iter.next();
- continue
- }
- None => {
- self.n = 0;
- return None
- }
- }
- }
- self.n = 0;
- next
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (lower, upper) = self.iter.size_hint();
-
- let lower = lower.saturating_sub(self.n);
-
- let upper = match upper {
- Some(x) => Some(x.saturating_sub(self.n)),
- None => None
- };
-
- (lower, upper)
- }
-}
-
-impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Skip<T> {
- #[inline]
- fn indexable(&self) -> uint {
- self.iter.indexable().saturating_sub(self.n)
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- if index >= self.indexable() {
- None
- } else {
- self.iter.idx(index + self.n)
- }
- }
-}
-
-/// An iterator which only iterates over the first `n` iterations of `iter`.
-#[deriving(Clone)]
-pub struct Take<T> {
- priv iter: T,
- priv n: uint
-}
-
-impl<A, T: Iterator<A>> Iterator<A> for Take<T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.n != 0 {
- self.n -= 1;
- self.iter.next()
- } else {
- None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (lower, upper) = self.iter.size_hint();
-
- let lower = cmp::min(lower, self.n);
-
- let upper = match upper {
- Some(x) if x < self.n => Some(x),
- _ => Some(self.n)
- };
-
- (lower, upper)
- }
-}
-
-impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
- #[inline]
- fn indexable(&self) -> uint {
- cmp::min(self.iter.indexable(), self.n)
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- if index >= self.n {
- None
- } else {
- self.iter.idx(index)
- }
- }
-}
-
-
-/// An iterator to maintain state while iterating another iterator
-pub struct Scan<'self, A, B, T, St> {
- priv iter: T,
- priv f: 'self |&mut St, A| -> Option<B>,
-
- /// The current internal state to be passed to the closure next.
- state: St
-}
-
-impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'self, A, B, T, St> {
- #[inline]
- fn next(&mut self) -> Option<B> {
- self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the scan function
- }
-}
-
-/// An iterator that maps each element to an iterator,
-/// and yields the elements of the produced iterators
-///
-pub struct FlatMap<'self, A, T, U> {
- priv iter: T,
- priv f: 'self |A| -> U,
- priv frontiter: Option<U>,
- priv backiter: Option<U>,
-}
-
-impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'self, A, T, U> {
- #[inline]
- fn next(&mut self) -> Option<B> {
- loop {
- for inner in self.frontiter.mut_iter() {
- for x in *inner {
- return Some(x)
- }
- }
- match self.iter.next().map(|x| (self.f)(x)) {
- None => return self.backiter.as_mut().and_then(|it| it.next()),
- next => self.frontiter = next,
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (flo, fhi) = self.frontiter.as_ref().map_default((0, Some(0)), |it| it.size_hint());
- let (blo, bhi) = self.backiter.as_ref().map_default((0, Some(0)), |it| it.size_hint());
- let lo = flo.saturating_add(blo);
- match (self.iter.size_hint(), fhi, bhi) {
- ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(&b)),
- _ => (lo, None)
- }
- }
-}
-
-impl<'self,
- A, T: DoubleEndedIterator<A>,
- B, U: DoubleEndedIterator<B>> DoubleEndedIterator<B>
- for FlatMap<'self, A, T, U> {
- #[inline]
- fn next_back(&mut self) -> Option<B> {
- loop {
- for inner in self.backiter.mut_iter() {
- match inner.next_back() {
- None => (),
- y => return y
- }
- }
- match self.iter.next_back().map(|x| (self.f)(x)) {
- None => return self.frontiter.as_mut().and_then(|it| it.next_back()),
- next => self.backiter = next,
- }
- }
- }
-}
-
-/// An iterator that yields `None` forever after the underlying iterator
-/// yields `None` once.
-#[deriving(Clone, DeepClone)]
-pub struct Fuse<T> {
- priv iter: T,
- priv done: bool
-}
-
-impl<A, T: Iterator<A>> Iterator<A> for Fuse<T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.done {
- None
- } else {
- match self.iter.next() {
- None => {
- self.done = true;
- None
- }
- x => x
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- if self.done {
- (0, Some(0))
- } else {
- self.iter.size_hint()
- }
- }
-}
-
-impl<A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Fuse<T> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- if self.done {
- None
- } else {
- match self.iter.next_back() {
- None => {
- self.done = true;
- None
- }
- x => x
- }
- }
- }
-}
-
-// Allow RandomAccessIterators to be fused without affecting random-access behavior
-impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Fuse<T> {
- #[inline]
- fn indexable(&self) -> uint {
- self.iter.indexable()
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- self.iter.idx(index)
- }
-}
-
-impl<T> Fuse<T> {
- /// Resets the fuse such that the next call to .next() or .next_back() will
- /// call the underlying iterator again even if it prevously returned None.
- #[inline]
- fn reset_fuse(&mut self) {
- self.done = false
- }
-}
-
-/// An iterator that calls a function with a reference to each
-/// element before yielding it.
-pub struct Inspect<'self, A, T> {
- priv iter: T,
- priv f: 'self |&A|
-}
-
-impl<'self, A, T> Inspect<'self, A, T> {
- #[inline]
- fn do_inspect(&self, elt: Option<A>) -> Option<A> {
- match elt {
- Some(ref a) => (self.f)(a),
- None => ()
- }
-
- elt
- }
-}
-
-impl<'self, A, T: Iterator<A>> Iterator<A> for Inspect<'self, A, T> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- let next = self.iter.next();
- self.do_inspect(next)
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A>
-for Inspect<'self, A, T> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- let next = self.iter.next_back();
- self.do_inspect(next)
- }
-}
-
-impl<'self, A, T: RandomAccessIterator<A>> RandomAccessIterator<A>
-for Inspect<'self, A, T> {
- #[inline]
- fn indexable(&self) -> uint {
- self.iter.indexable()
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<A> {
- self.do_inspect(self.iter.idx(index))
- }
-}
-
-/// An iterator which just modifies the contained state throughout iteration.
-pub struct Unfold<'self, A, St> {
- priv f: 'self |&mut St| -> Option<A>,
- /// Internal state that will be yielded on the next iteration
- state: St
-}
-
-impl<'self, A, St> Unfold<'self, A, St> {
- /// Creates a new iterator with the specified closure as the "iterator
- /// function" and an initial state to eventually pass to the iterator
- #[inline]
- pub fn new<'a>(initial_state: St, f: 'a |&mut St| -> Option<A>)
- -> Unfold<'a, A, St> {
- Unfold {
- f: f,
- state: initial_state
- }
- }
-}
-
-impl<'self, A, St> Iterator<A> for Unfold<'self, A, St> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- (self.f)(&mut self.state)
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- // no possible known bounds at this point
- (0, None)
- }
-}
-
-/// An infinite iterator starting at `start` and advancing by `step` with each
-/// iteration
-#[deriving(Clone)]
-pub struct Counter<A> {
- /// The current state the counter is at (next value to be yielded)
- priv state: A,
- /// The amount that this iterator is stepping by
- priv step: A
-}
-
-/// Creates a new counter with the specified start/step
-#[inline]
-pub fn count<A>(start: A, step: A) -> Counter<A> {
- Counter{state: start, step: step}
-}
-
-impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- let result = self.state.clone();
- self.state = self.state + self.step;
- Some(result)
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (uint::max_value, None) // Too bad we can't specify an infinite lower bound
- }
-}
-
-/// An iterator over the range [start, stop)
-#[deriving(Clone, DeepClone)]
-pub struct Range<A> {
- priv state: A,
- priv stop: A,
- priv one: A
-}
-
-/// Return an iterator over the range [start, stop)
-#[inline]
-pub fn range<A: Add<A, A> + Ord + Clone + One>(start: A, stop: A) -> Range<A> {
- Range{state: start, stop: stop, one: One::one()}
-}
-
-// FIXME: #10414: Unfortunate type bound
-impl<A: Add<A, A> + Ord + Clone + ToPrimitive> Iterator<A> for Range<A> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.state < self.stop {
- let result = self.state.clone();
- self.state = self.state + self.one;
- Some(result)
- } else {
- None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- // This first checks if the elements are representable as i64. If they aren't, try u64 (to
- // handle cases like range(huge, huger)). We don't use uint/int because the difference of
- // the i64/u64 might lie within their range.
- let bound = match self.state.to_i64() {
- Some(a) => {
- let sz = self.stop.to_i64().map(|b| b.checked_sub(&a));
- match sz {
- Some(Some(bound)) => bound.to_uint(),
- _ => None,
- }
- },
- None => match self.state.to_u64() {
- Some(a) => {
- let sz = self.stop.to_u64().map(|b| b.checked_sub(&a));
- match sz {
- Some(Some(bound)) => bound.to_uint(),
- _ => None
- }
- },
- None => None
- }
- };
-
- match bound {
- Some(b) => (b, Some(b)),
- // Standard fallback for unbounded/unrepresentable bounds
- None => (0, None)
- }
- }
-}
-
-/// `Integer` is required to ensure the range will be the same regardless of
-/// the direction it is consumed.
-impl<A: Integer + Ord + Clone + ToPrimitive> DoubleEndedIterator<A> for Range<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- if self.stop > self.state {
- self.stop = self.stop - self.one;
- Some(self.stop.clone())
- } else {
- None
- }
- }
-}
-
-/// An iterator over the range [start, stop]
-#[deriving(Clone, DeepClone)]
-pub struct RangeInclusive<A> {
- priv range: Range<A>,
- priv done: bool
-}
-
-/// Return an iterator over the range [start, stop]
-#[inline]
-pub fn range_inclusive<A: Add<A, A> + Ord + Clone + One + ToPrimitive>(start: A, stop: A)
- -> RangeInclusive<A> {
- RangeInclusive{range: range(start, stop), done: false}
-}
-
-impl<A: Add<A, A> + Eq + Ord + Clone + ToPrimitive> Iterator<A> for RangeInclusive<A> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- match self.range.next() {
- Some(x) => Some(x),
- None => {
- if !self.done && self.range.state == self.range.stop {
- self.done = true;
- Some(self.range.stop.clone())
- } else {
- None
- }
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (lo, hi) = self.range.size_hint();
- if self.done {
- (lo, hi)
- } else {
- let lo = lo.saturating_add(1);
- let hi = match hi {
- Some(x) => x.checked_add(&1),
- None => None
- };
- (lo, hi)
- }
- }
-}
-
-impl<A: Sub<A, A> + Integer + Ord + Clone + ToPrimitive> DoubleEndedIterator<A>
- for RangeInclusive<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- if self.range.stop > self.range.state {
- let result = self.range.stop.clone();
- self.range.stop = self.range.stop - self.range.one;
- Some(result)
- } else if !self.done && self.range.state == self.range.stop {
- self.done = true;
- Some(self.range.stop.clone())
- } else {
- None
- }
- }
-}
-
-/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
-#[deriving(Clone, DeepClone)]
-pub struct RangeStep<A> {
- priv state: A,
- priv stop: A,
- priv step: A,
- priv rev: bool
-}
-
-/// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
-#[inline]
-pub fn range_step<A: CheckedAdd + Ord + Clone + Zero>(start: A, stop: A, step: A) -> RangeStep<A> {
- let rev = step < Zero::zero();
- RangeStep{state: start, stop: stop, step: step, rev: rev}
-}
-
-impl<A: CheckedAdd + Ord + Clone> Iterator<A> for RangeStep<A> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
- let result = self.state.clone();
- match self.state.checked_add(&self.step) {
- Some(x) => self.state = x,
- None => self.state = self.stop.clone()
- }
- Some(result)
- } else {
- None
- }
- }
-}
-
-/// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
-#[deriving(Clone, DeepClone)]
-pub struct RangeStepInclusive<A> {
- priv state: A,
- priv stop: A,
- priv step: A,
- priv rev: bool,
- priv done: bool
-}
-
-/// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
-#[inline]
-pub fn range_step_inclusive<A: CheckedAdd + Ord + Clone + Zero>(start: A, stop: A,
- step: A) -> RangeStepInclusive<A> {
- let rev = step < Zero::zero();
- RangeStepInclusive{state: start, stop: stop, step: step, rev: rev, done: false}
-}
-
-impl<A: CheckedAdd + Ord + Clone + Eq> Iterator<A> for RangeStepInclusive<A> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- if !self.done && ((self.rev && self.state >= self.stop) ||
- (!self.rev && self.state <= self.stop)) {
- let result = self.state.clone();
- match self.state.checked_add(&self.step) {
- Some(x) => self.state = x,
- None => self.done = true
- }
- Some(result)
- } else {
- None
- }
- }
-}
-
-/// An iterator that repeats an element endlessly
-#[deriving(Clone, DeepClone)]
-pub struct Repeat<A> {
- priv element: A
-}
-
-impl<A: Clone> Repeat<A> {
- /// Create a new `Repeat` that endlessly repeats the element `elt`.
- #[inline]
- pub fn new(elt: A) -> Repeat<A> {
- Repeat{element: elt}
- }
-}
-
-impl<A: Clone> Iterator<A> for Repeat<A> {
- #[inline]
- fn next(&mut self) -> Option<A> { self.idx(0) }
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) { (uint::max_value, None) }
-}
-
-impl<A: Clone> DoubleEndedIterator<A> for Repeat<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A> { self.idx(0) }
-}
-
-impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
- #[inline]
- fn indexable(&self) -> uint { uint::max_value }
- #[inline]
- fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
-}
-
-/// Functions for lexicographical ordering of sequences.
-///
-/// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires
-/// that the elements implement both `Eq` and `Ord`.
-///
-/// If two sequences are equal up until the point where one ends,
-/// the shorter sequence compares less.
-pub mod order {
- use cmp;
- use cmp::{TotalEq, TotalOrd, Ord, Eq};
- use option::{Some, None};
- use super::Iterator;
-
- /// Compare `a` and `b` for equality using `TotalOrd`
- pub fn equals<A: TotalEq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return true,
- (None, _) | (_, None) => return false,
- (Some(x), Some(y)) => if !x.equals(&y) { return false },
- }
- }
- }
-
- /// Order `a` and `b` lexicographically using `TotalOrd`
- pub fn cmp<A: TotalOrd, T: Iterator<A>>(mut a: T, mut b: T) -> cmp::Ordering {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return cmp::Equal,
- (None, _ ) => return cmp::Less,
- (_ , None) => return cmp::Greater,
- (Some(x), Some(y)) => match x.cmp(&y) {
- cmp::Equal => (),
- non_eq => return non_eq,
- },
- }
- }
- }
-
- /// Compare `a` and `b` for equality (Using partial equality, `Eq`)
- pub fn eq<A: Eq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return true,
- (None, _) | (_, None) => return false,
- (Some(x), Some(y)) => if !x.eq(&y) { return false },
- }
- }
- }
-
- /// Compare `a` and `b` for nonequality (Using partial equality, `Eq`)
- pub fn ne<A: Eq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return false,
- (None, _) | (_, None) => return true,
- (Some(x), Some(y)) => if x.ne(&y) { return true },
- }
- }
- }
-
- /// Return `a` < `b` lexicographically (Using partial order, `Ord`)
- pub fn lt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return false,
- (None, _ ) => return true,
- (_ , None) => return false,
- (Some(x), Some(y)) => if x.ne(&y) { return x.lt(&y) },
- }
- }
- }
-
- /// Return `a` <= `b` lexicographically (Using partial order, `Ord`)
- pub fn le<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return true,
- (None, _ ) => return true,
- (_ , None) => return false,
- (Some(x), Some(y)) => if x.ne(&y) { return x.le(&y) },
- }
- }
- }
-
- /// Return `a` > `b` lexicographically (Using partial order, `Ord`)
- pub fn gt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return false,
- (None, _ ) => return false,
- (_ , None) => return true,
- (Some(x), Some(y)) => if x.ne(&y) { return x.gt(&y) },
- }
- }
- }
-
- /// Return `a` >= `b` lexicographically (Using partial order, `Ord`)
- pub fn ge<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
- loop {
- match (a.next(), b.next()) {
- (None, None) => return true,
- (None, _ ) => return false,
- (_ , None) => return true,
- (Some(x), Some(y)) => if x.ne(&y) { return x.ge(&y) },
- }
- }
- }
-
- #[test]
- fn test_lt() {
- use vec::ImmutableVector;
-
- let empty: [int, ..0] = [];
- let xs = [1,2,3];
- let ys = [1,2,0];
-
- assert!(!lt(xs.iter(), ys.iter()));
- assert!(!le(xs.iter(), ys.iter()));
- assert!( gt(xs.iter(), ys.iter()));
- assert!( ge(xs.iter(), ys.iter()));
-
- assert!( lt(ys.iter(), xs.iter()));
- assert!( le(ys.iter(), xs.iter()));
- assert!(!gt(ys.iter(), xs.iter()));
- assert!(!ge(ys.iter(), xs.iter()));
-
- assert!( lt(empty.iter(), xs.iter()));
- assert!( le(empty.iter(), xs.iter()));
- assert!(!gt(empty.iter(), xs.iter()));
- assert!(!ge(empty.iter(), xs.iter()));
-
- // Sequence with NaN
- let u = [1.0, 2.0];
- let v = [0.0/0.0, 3.0];
-
- assert!(!lt(u.iter(), v.iter()));
- assert!(!le(u.iter(), v.iter()));
- assert!(!gt(u.iter(), v.iter()));
- assert!(!ge(u.iter(), v.iter()));
-
- let a = [0.0/0.0];
- let b = [1.0];
- let c = [2.0];
-
- assert!(lt(a.iter(), b.iter()) == (a[0] < b[0]));
- assert!(le(a.iter(), b.iter()) == (a[0] <= b[0]));
- assert!(gt(a.iter(), b.iter()) == (a[0] > b[0]));
- assert!(ge(a.iter(), b.iter()) == (a[0] >= b[0]));
-
- assert!(lt(c.iter(), b.iter()) == (c[0] < b[0]));
- assert!(le(c.iter(), b.iter()) == (c[0] <= b[0]));
- assert!(gt(c.iter(), b.iter()) == (c[0] > b[0]));
- assert!(ge(c.iter(), b.iter()) == (c[0] >= b[0]));
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use prelude::*;
-
- use cmp;
- use uint;
- use num;
-
- #[test]
- fn test_counter_from_iter() {
- let mut it = count(0, 5).take(10);
- let xs: ~[int] = FromIterator::from_iterator(&mut it);
- assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
- }
-
- #[test]
- fn test_iterator_chain() {
- let xs = [0u, 1, 2, 3, 4, 5];
- let ys = [30u, 40, 50, 60];
- let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
- let mut it = xs.iter().chain(ys.iter());
- let mut i = 0;
- for &x in it {
- assert_eq!(x, expected[i]);
- i += 1;
- }
- assert_eq!(i, expected.len());
-
- let ys = count(30u, 10).take(4);
- let mut it = xs.iter().map(|&x| x).chain(ys);
- let mut i = 0;
- for x in it {
- assert_eq!(x, expected[i]);
- i += 1;
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_filter_map() {
- let mut it = count(0u, 1u).take(10)
- .filter_map(|x| if x.is_even() { Some(x*x) } else { None });
- assert_eq!(it.collect::<~[uint]>(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
- }
-
- #[test]
- fn test_iterator_enumerate() {
- let xs = [0u, 1, 2, 3, 4, 5];
- let mut it = xs.iter().enumerate();
- for (i, &x) in it {
- assert_eq!(i, x);
- }
- }
-
- #[test]
- fn test_iterator_peekable() {
- let xs = ~[0u, 1, 2, 3, 4, 5];
- let mut it = xs.iter().map(|&x|x).peekable();
- assert_eq!(it.peek().unwrap(), &0);
- assert_eq!(it.next().unwrap(), 0);
- assert_eq!(it.next().unwrap(), 1);
- assert_eq!(it.next().unwrap(), 2);
- assert_eq!(it.peek().unwrap(), &3);
- assert_eq!(it.peek().unwrap(), &3);
- assert_eq!(it.next().unwrap(), 3);
- assert_eq!(it.next().unwrap(), 4);
- assert_eq!(it.peek().unwrap(), &5);
- assert_eq!(it.next().unwrap(), 5);
- assert!(it.peek().is_none());
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_iterator_take_while() {
- let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
- let ys = [0u, 1, 2, 3, 5, 13];
- let mut it = xs.iter().take_while(|&x| *x < 15u);
- let mut i = 0;
- for &x in it {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, ys.len());
- }
-
- #[test]
- fn test_iterator_skip_while() {
- let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
- let ys = [15, 16, 17, 19];
- let mut it = xs.iter().skip_while(|&x| *x < 15u);
- let mut i = 0;
- for &x in it {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, ys.len());
- }
-
- #[test]
- fn test_iterator_skip() {
- let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
- let ys = [13, 15, 16, 17, 19, 20, 30];
- let mut it = xs.iter().skip(5);
- let mut i = 0;
- for &x in it {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, ys.len());
- }
-
- #[test]
- fn test_iterator_take() {
- let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
- let ys = [0u, 1, 2, 3, 5];
- let mut it = xs.iter().take(5);
- let mut i = 0;
- for &x in it {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, ys.len());
- }
-
- #[test]
- fn test_iterator_scan() {
- // test the type inference
- fn add(old: &mut int, new: &uint) -> Option<f64> {
- *old += *new as int;
- Some(*old as f64)
- }
- let xs = [0u, 1, 2, 3, 4];
- let ys = [0f64, 1.0, 3.0, 6.0, 10.0];
-
- let mut it = xs.iter().scan(0, add);
- let mut i = 0;
- for x in it {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, ys.len());
- }
-
- #[test]
- fn test_iterator_flat_map() {
- let xs = [0u, 3, 6];
- let ys = [0u, 1, 2, 3, 4, 5, 6, 7, 8];
- let mut it = xs.iter().flat_map(|&x| count(x, 1).take(3));
- let mut i = 0;
- for x in it {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, ys.len());
- }
-
- #[test]
- fn test_inspect() {
- let xs = [1u, 2, 3, 4];
- let mut n = 0;
-
- let ys = xs.iter()
- .map(|&x| x)
- .inspect(|_| n += 1)
- .collect::<~[uint]>();
-
- assert_eq!(n, xs.len());
- assert_eq!(xs, ys.as_slice());
- }
-
- #[test]
- fn test_unfoldr() {
- fn count(st: &mut uint) -> Option<uint> {
- if *st < 10 {
- let ret = Some(*st);
- *st += 1;
- ret
- } else {
- None
- }
- }
-
- let mut it = Unfold::new(0, count);
- let mut i = 0;
- for counted in it {
- assert_eq!(counted, i);
- i += 1;
- }
- assert_eq!(i, 10);
- }
-
- #[test]
- fn test_cycle() {
- let cycle_len = 3;
- let it = count(0u, 1).take(cycle_len).cycle();
- assert_eq!(it.size_hint(), (uint::max_value, None));
- for (i, x) in it.take(100).enumerate() {
- assert_eq!(i % cycle_len, x);
- }
-
- let mut it = count(0u, 1).take(0).cycle();
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert_eq!(it.next(), None);
- }
-
- #[test]
- fn test_iterator_nth() {
- let v = &[0, 1, 2, 3, 4];
- for i in range(0u, v.len()) {
- assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
- }
- }
-
- #[test]
- fn test_iterator_last() {
- let v = &[0, 1, 2, 3, 4];
- assert_eq!(v.iter().last().unwrap(), &4);
- assert_eq!(v.slice(0, 1).iter().last().unwrap(), &0);
- }
-
- #[test]
- fn test_iterator_len() {
- let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- assert_eq!(v.slice(0, 4).iter().len(), 4);
- assert_eq!(v.slice(0, 10).iter().len(), 10);
- assert_eq!(v.slice(0, 0).iter().len(), 0);
- }
-
- #[test]
- fn test_iterator_sum() {
- let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- assert_eq!(v.slice(0, 4).iter().map(|&x| x).sum(), 6);
- assert_eq!(v.iter().map(|&x| x).sum(), 55);
- assert_eq!(v.slice(0, 0).iter().map(|&x| x).sum(), 0);
- }
-
- #[test]
- fn test_iterator_product() {
- let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- assert_eq!(v.slice(0, 4).iter().map(|&x| x).product(), 0);
- assert_eq!(v.slice(1, 5).iter().map(|&x| x).product(), 24);
- assert_eq!(v.slice(0, 0).iter().map(|&x| x).product(), 1);
- }
-
- #[test]
- fn test_iterator_max() {
- let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- assert_eq!(v.slice(0, 4).iter().map(|&x| x).max(), Some(3));
- assert_eq!(v.iter().map(|&x| x).max(), Some(10));
- assert_eq!(v.slice(0, 0).iter().map(|&x| x).max(), None);
- }
-
- #[test]
- fn test_iterator_min() {
- let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- assert_eq!(v.slice(0, 4).iter().map(|&x| x).min(), Some(0));
- assert_eq!(v.iter().map(|&x| x).min(), Some(0));
- assert_eq!(v.slice(0, 0).iter().map(|&x| x).min(), None);
- }
-
- #[test]
- fn test_iterator_size_hint() {
- let c = count(0, 1);
- let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
- let v2 = &[10, 11, 12];
- let vi = v.iter();
-
- assert_eq!(c.size_hint(), (uint::max_value, None));
- assert_eq!(vi.size_hint(), (10, Some(10)));
-
- assert_eq!(c.take(5).size_hint(), (5, Some(5)));
- assert_eq!(c.skip(5).size_hint().second(), None);
- assert_eq!(c.take_while(|_| false).size_hint(), (0, None));
- assert_eq!(c.skip_while(|_| false).size_hint(), (0, None));
- assert_eq!(c.enumerate().size_hint(), (uint::max_value, None));
- assert_eq!(c.chain(vi.map(|&i| i)).size_hint(), (uint::max_value, None));
- assert_eq!(c.zip(vi).size_hint(), (10, Some(10)));
- assert_eq!(c.scan(0, |_,_| Some(0)).size_hint(), (0, None));
- assert_eq!(c.filter(|_| false).size_hint(), (0, None));
- assert_eq!(c.map(|_| 0).size_hint(), (uint::max_value, None));
- assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
-
- assert_eq!(vi.take(5).size_hint(), (5, Some(5)));
- assert_eq!(vi.take(12).size_hint(), (10, Some(10)));
- assert_eq!(vi.skip(3).size_hint(), (7, Some(7)));
- assert_eq!(vi.skip(12).size_hint(), (0, Some(0)));
- assert_eq!(vi.take_while(|_| false).size_hint(), (0, Some(10)));
- assert_eq!(vi.skip_while(|_| false).size_hint(), (0, Some(10)));
- assert_eq!(vi.enumerate().size_hint(), (10, Some(10)));
- assert_eq!(vi.chain(v2.iter()).size_hint(), (13, Some(13)));
- assert_eq!(vi.zip(v2.iter()).size_hint(), (3, Some(3)));
- assert_eq!(vi.scan(0, |_,_| Some(0)).size_hint(), (0, Some(10)));
- assert_eq!(vi.filter(|_| false).size_hint(), (0, Some(10)));
- assert_eq!(vi.map(|i| i+1).size_hint(), (10, Some(10)));
- assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10)));
- }
-
- #[test]
- fn test_collect() {
- let a = ~[1, 2, 3, 4, 5];
- let b: ~[int] = a.iter().map(|&x| x).collect();
- assert_eq!(a, b);
- }
-
- #[test]
- fn test_all() {
- let v: ~&[int] = ~&[1, 2, 3, 4, 5];
- assert!(v.iter().all(|&x| x < 10));
- assert!(!v.iter().all(|&x| x.is_even()));
- assert!(!v.iter().all(|&x| x > 100));
- assert!(v.slice(0, 0).iter().all(|_| fail!()));
- }
-
- #[test]
- fn test_any() {
- let v: ~&[int] = ~&[1, 2, 3, 4, 5];
- assert!(v.iter().any(|&x| x < 10));
- assert!(v.iter().any(|&x| x.is_even()));
- assert!(!v.iter().any(|&x| x > 100));
- assert!(!v.slice(0, 0).iter().any(|_| fail!()));
- }
-
- #[test]
- fn test_find() {
- let v: &[int] = &[1, 3, 9, 27, 103, 14, 11];
- assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14);
- assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3);
- assert!(v.iter().find(|x| *x % 12 == 0).is_none());
- }
-
- #[test]
- fn test_position() {
- let v = &[1, 3, 9, 27, 103, 14, 11];
- assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
- assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1);
- assert!(v.iter().position(|x| *x % 12 == 0).is_none());
- }
-
- #[test]
- fn test_count() {
- let xs = &[1, 2, 2, 1, 5, 9, 0, 2];
- assert_eq!(xs.iter().count(|x| *x == 2), 3);
- assert_eq!(xs.iter().count(|x| *x == 5), 1);
- assert_eq!(xs.iter().count(|x| *x == 95), 0);
- }
-
- #[test]
- fn test_max_by() {
- let xs: &[int] = &[-3, 0, 1, 5, -10];
- assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
- }
-
- #[test]
- fn test_min_by() {
- let xs: &[int] = &[-3, 0, 1, 5, -10];
- assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
- }
-
- #[test]
- fn test_by_ref() {
- let mut xs = range(0, 10);
- // sum the first five values
- let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
- assert_eq!(partial_sum, 10);
- assert_eq!(xs.next(), Some(5));
- }
-
- #[test]
- fn test_invert() {
- let xs = [2, 4, 6, 8, 10, 12, 14, 16];
- let mut it = xs.iter();
- it.next();
- it.next();
- assert_eq!(it.invert().map(|&x| x).collect::<~[int]>(), ~[16, 14, 12, 10, 8, 6]);
- }
-
- #[test]
- fn test_double_ended_map() {
- let xs = [1, 2, 3, 4, 5, 6];
- let mut it = xs.iter().map(|&x| x * -1);
- assert_eq!(it.next(), Some(-1));
- assert_eq!(it.next(), Some(-2));
- assert_eq!(it.next_back(), Some(-6));
- assert_eq!(it.next_back(), Some(-5));
- assert_eq!(it.next(), Some(-3));
- assert_eq!(it.next_back(), Some(-4));
- assert_eq!(it.next(), None);
- }
-
- #[test]
- fn test_double_ended_enumerate() {
- let xs = [1, 2, 3, 4, 5, 6];
- let mut it = xs.iter().map(|&x| x).enumerate();
- assert_eq!(it.next(), Some((0, 1)));
- assert_eq!(it.next(), Some((1, 2)));
- assert_eq!(it.next_back(), Some((5, 6)));
- assert_eq!(it.next_back(), Some((4, 5)));
- assert_eq!(it.next_back(), Some((3, 4)));
- assert_eq!(it.next_back(), Some((2, 3)));
- assert_eq!(it.next(), None);
- }
-
- #[test]
- fn test_double_ended_zip() {
- let xs = [1, 2, 3, 4, 5, 6];
- let ys = [1, 2, 3, 7];
- let a = xs.iter().map(|&x| x);
- let b = ys.iter().map(|&x| x);
- let mut it = a.zip(b);
- assert_eq!(it.next(), Some((1, 1)));
- assert_eq!(it.next(), Some((2, 2)));
- assert_eq!(it.next_back(), Some((4, 7)));
- assert_eq!(it.next_back(), Some((3, 3)));
- assert_eq!(it.next(), None);
- }
-
- #[test]
- fn test_double_ended_filter() {
- let xs = [1, 2, 3, 4, 5, 6];
- let mut it = xs.iter().filter(|&x| *x & 1 == 0);
- assert_eq!(it.next_back().unwrap(), &6);
- assert_eq!(it.next_back().unwrap(), &4);
- assert_eq!(it.next().unwrap(), &2);
- assert_eq!(it.next_back(), None);
- }
-
- #[test]
- fn test_double_ended_filter_map() {
- let xs = [1, 2, 3, 4, 5, 6];
- let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
- assert_eq!(it.next_back().unwrap(), 12);
- assert_eq!(it.next_back().unwrap(), 8);
- assert_eq!(it.next().unwrap(), 4);
- assert_eq!(it.next_back(), None);
- }
-
- #[test]
- fn test_double_ended_chain() {
- let xs = [1, 2, 3, 4, 5];
- let ys = ~[7, 9, 11];
- let mut it = xs.iter().chain(ys.iter()).invert();
- assert_eq!(it.next().unwrap(), &11)
- assert_eq!(it.next().unwrap(), &9)
- assert_eq!(it.next_back().unwrap(), &1)
- assert_eq!(it.next_back().unwrap(), &2)
- assert_eq!(it.next_back().unwrap(), &3)
- assert_eq!(it.next_back().unwrap(), &4)
- assert_eq!(it.next_back().unwrap(), &5)
- assert_eq!(it.next_back().unwrap(), &7)
- assert_eq!(it.next_back(), None)
- }
-
- #[test]
- fn test_rposition() {
- fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
- fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
- let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
-
- assert_eq!(v.iter().rposition(f), Some(3u));
- assert!(v.iter().rposition(g).is_none());
- }
-
- #[test]
- #[should_fail]
- fn test_rposition_fail() {
- let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
- let mut i = 0;
- v.iter().rposition(|_elt| {
- if i == 2 {
- fail!()
- }
- i += 1;
- false
- });
- }
-
-
- #[cfg(test)]
- fn check_randacc_iter<A: Eq, T: Clone + RandomAccessIterator<A>>(a: T, len: uint)
- {
- let mut b = a.clone();
- assert_eq!(len, b.indexable());
- let mut n = 0;
- for (i, elt) in a.enumerate() {
- assert_eq!(Some(elt), b.idx(i));
- n += 1;
- }
- assert_eq!(n, len);
- assert_eq!(None, b.idx(n));
- // call recursively to check after picking off an element
- if len > 0 {
- b.next();
- check_randacc_iter(b, len-1);
- }
- }
-
-
- #[test]
- fn test_double_ended_flat_map() {
- let u = [0u,1];
- let v = [5,6,7,8];
- let mut it = u.iter().flat_map(|x| v.slice(*x, v.len()).iter());
- assert_eq!(it.next_back().unwrap(), &8);
- assert_eq!(it.next().unwrap(), &5);
- assert_eq!(it.next_back().unwrap(), &7);
- assert_eq!(it.next_back().unwrap(), &6);
- assert_eq!(it.next_back().unwrap(), &8);
- assert_eq!(it.next().unwrap(), &6);
- assert_eq!(it.next_back().unwrap(), &7);
- assert_eq!(it.next_back(), None);
- assert_eq!(it.next(), None);
- assert_eq!(it.next_back(), None);
- }
-
- #[test]
- fn test_random_access_chain() {
- let xs = [1, 2, 3, 4, 5];
- let ys = ~[7, 9, 11];
- let mut it = xs.iter().chain(ys.iter());
- assert_eq!(it.idx(0).unwrap(), &1);
- assert_eq!(it.idx(5).unwrap(), &7);
- assert_eq!(it.idx(7).unwrap(), &11);
- assert!(it.idx(8).is_none());
-
- it.next();
- it.next();
- it.next_back();
-
- assert_eq!(it.idx(0).unwrap(), &3);
- assert_eq!(it.idx(4).unwrap(), &9);
- assert!(it.idx(6).is_none());
-
- check_randacc_iter(it, xs.len() + ys.len() - 3);
- }
-
- #[test]
- fn test_random_access_enumerate() {
- let xs = [1, 2, 3, 4, 5];
- check_randacc_iter(xs.iter().enumerate(), xs.len());
- }
-
- #[test]
- fn test_random_access_invert() {
- let xs = [1, 2, 3, 4, 5];
- check_randacc_iter(xs.iter().invert(), xs.len());
- let mut it = xs.iter().invert();
- it.next();
- it.next_back();
- it.next();
- check_randacc_iter(it, xs.len() - 3);
- }
-
- #[test]
- fn test_random_access_zip() {
- let xs = [1, 2, 3, 4, 5];
- let ys = [7, 9, 11];
- check_randacc_iter(xs.iter().zip(ys.iter()), cmp::min(xs.len(), ys.len()));
- }
-
- #[test]
- fn test_random_access_take() {
- let xs = [1, 2, 3, 4, 5];
- let empty: &[int] = [];
- check_randacc_iter(xs.iter().take(3), 3);
- check_randacc_iter(xs.iter().take(20), xs.len());
- check_randacc_iter(xs.iter().take(0), 0);
- check_randacc_iter(empty.iter().take(2), 0);
- }
-
- #[test]
- fn test_random_access_skip() {
- let xs = [1, 2, 3, 4, 5];
- let empty: &[int] = [];
- check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
- check_randacc_iter(empty.iter().skip(2), 0);
- }
-
- #[test]
- fn test_random_access_inspect() {
- let xs = [1, 2, 3, 4, 5];
-
- // test .map and .inspect that don't implement Clone
- let it = xs.iter().inspect(|_| {});
- assert_eq!(xs.len(), it.indexable());
- for (i, elt) in xs.iter().enumerate() {
- assert_eq!(Some(elt), it.idx(i));
- }
-
- }
-
- #[test]
- fn test_random_access_map() {
- let xs = [1, 2, 3, 4, 5];
-
- let it = xs.iter().map(|x| *x);
- assert_eq!(xs.len(), it.indexable());
- for (i, elt) in xs.iter().enumerate() {
- assert_eq!(Some(*elt), it.idx(i));
- }
- }
-
- #[test]
- fn test_random_access_cycle() {
- let xs = [1, 2, 3, 4, 5];
- let empty: &[int] = [];
- check_randacc_iter(xs.iter().cycle().take(27), 27);
- check_randacc_iter(empty.iter().cycle(), 0);
- }
-
- #[test]
- fn test_double_ended_range() {
- assert_eq!(range(11i, 14).invert().collect::<~[int]>(), ~[13i, 12, 11]);
- for _ in range(10i, 0).invert() {
- fail!("unreachable");
- }
-
- assert_eq!(range(11u, 14).invert().collect::<~[uint]>(), ~[13u, 12, 11]);
- for _ in range(10u, 0).invert() {
- fail!("unreachable");
- }
- }
-
- #[test]
- fn test_range() {
- /// A mock type to check Range when ToPrimitive returns None
- struct Foo;
-
- impl ToPrimitive for Foo {
- fn to_i64(&self) -> Option<i64> { None }
- fn to_u64(&self) -> Option<u64> { None }
- }
-
- impl Add<Foo, Foo> for Foo {
- fn add(&self, _: &Foo) -> Foo {
- Foo
- }
- }
-
- impl Ord for Foo {
- fn lt(&self, _: &Foo) -> bool {
- false
- }
- }
-
- impl Clone for Foo {
- fn clone(&self) -> Foo {
- Foo
- }
- }
-
- impl num::One for Foo {
- fn one() -> Foo {
- Foo
- }
- }
-
- assert_eq!(range(0i, 5).collect::<~[int]>(), ~[0i, 1, 2, 3, 4]);
- assert_eq!(range(-10i, -1).collect::<~[int]>(), ~[-10, -9, -8, -7, -6, -5, -4, -3, -2]);
- assert_eq!(range(0i, 5).invert().collect::<~[int]>(), ~[4, 3, 2, 1, 0]);
- assert_eq!(range(200, -5).collect::<~[int]>(), ~[]);
- assert_eq!(range(200, -5).invert().collect::<~[int]>(), ~[]);
- assert_eq!(range(200, 200).collect::<~[int]>(), ~[]);
- assert_eq!(range(200, 200).invert().collect::<~[int]>(), ~[]);
-
- assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
- // this test is only meaningful when sizeof uint < sizeof u64
- assert_eq!(range(uint::max_value - 1, uint::max_value).size_hint(), (1, Some(1)));
- assert_eq!(range(-10i, -1).size_hint(), (9, Some(9)));
- assert_eq!(range(Foo, Foo).size_hint(), (0, None));
- }
-
- #[test]
- fn test_range_inclusive() {
- assert_eq!(range_inclusive(0i, 5).collect::<~[int]>(), ~[0i, 1, 2, 3, 4, 5]);
- assert_eq!(range_inclusive(0i, 5).invert().collect::<~[int]>(), ~[5i, 4, 3, 2, 1, 0]);
- assert_eq!(range_inclusive(200, -5).collect::<~[int]>(), ~[]);
- assert_eq!(range_inclusive(200, -5).invert().collect::<~[int]>(), ~[]);
- assert_eq!(range_inclusive(200, 200).collect::<~[int]>(), ~[200]);
- assert_eq!(range_inclusive(200, 200).invert().collect::<~[int]>(), ~[200]);
- }
-
- #[test]
- fn test_range_step() {
- assert_eq!(range_step(0i, 20, 5).collect::<~[int]>(), ~[0, 5, 10, 15]);
- assert_eq!(range_step(20i, 0, -5).collect::<~[int]>(), ~[20, 15, 10, 5]);
- assert_eq!(range_step(20i, 0, -6).collect::<~[int]>(), ~[20, 14, 8, 2]);
- assert_eq!(range_step(200u8, 255, 50).collect::<~[u8]>(), ~[200u8, 250]);
- assert_eq!(range_step(200, -5, 1).collect::<~[int]>(), ~[]);
- assert_eq!(range_step(200, 200, 1).collect::<~[int]>(), ~[]);
- }
-
- #[test]
- fn test_range_step_inclusive() {
- assert_eq!(range_step_inclusive(0i, 20, 5).collect::<~[int]>(), ~[0, 5, 10, 15, 20]);
- assert_eq!(range_step_inclusive(20i, 0, -5).collect::<~[int]>(), ~[20, 15, 10, 5, 0]);
- assert_eq!(range_step_inclusive(20i, 0, -6).collect::<~[int]>(), ~[20, 14, 8, 2]);
- assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<~[u8]>(), ~[200u8, 250]);
- assert_eq!(range_step_inclusive(200, -5, 1).collect::<~[int]>(), ~[]);
- assert_eq!(range_step_inclusive(200, 200, 1).collect::<~[int]>(), ~[200]);
- }
-
- #[test]
- fn test_reverse() {
- let mut ys = [1, 2, 3, 4, 5];
- ys.mut_iter().reverse_();
- assert_eq!(ys, [5, 4, 3, 2, 1]);
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-The kind traits
-
-Rust types can be classified in various useful ways according to
-intrinsic properties of the type. These classifications, often called
-'kinds', are represented as traits.
-
-They cannot be implemented by user code, but are instead implemented
-by the compiler automatically for the types to which they apply.
-
-*/
-
-/// Types able to be transferred across task boundaries.
-#[lang="send"]
-pub trait Send {
- // empty.
-}
-
-/// Types that are either immutable or have inherited mutability.
-#[lang="freeze"]
-pub trait Freeze {
- // empty.
-}
-
-/// Types with a constant size known at compile-time.
-#[lang="sized"]
-pub trait Sized {
- // Empty.
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! # The Rust standard library
-//!
-//! The Rust standard library is a group of interrelated modules defining
-//! the core language traits, operations on built-in data types, collections,
-//! platform abstractions, the task scheduler, runtime support for language
-//! features and other common functionality.
-//!
-//! `std` includes modules corresponding to each of the integer types,
-//! each of the floating point types, the `bool` type, tuples, characters,
-//! strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
-//! boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
-//! Additionally, `std` provides pervasive types (`option` and `result`),
-//! task creation and communication primitives (`task`, `comm`), platform
-//! abstractions (`os` and `path`), basic I/O abstractions (`io`), common
-//! traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings
-//! to the C standard library (`libc`).
-//!
-//! # Standard library injection and the Rust prelude
-//!
-//! `std` is imported at the topmost level of every crate by default, as
-//! if the first line of each crate was
-//!
-//! extern mod std;
-//!
-//! This means that the contents of std can be accessed from any context
-//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
-//! etc.
-//!
-//! Additionally, `std` contains a `prelude` module that reexports many of the
-//! most common types, traits and functions. The contents of the prelude are
-//! imported into every *module* by default. Implicitly, all modules behave as if
-//! they contained the following prologue:
-//!
-//! use std::prelude::*;
-
-#[link(name = "std",
- package_id = "std",
- vers = "0.9-pre",
- uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
- url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
-
-#[comment = "The Rust standard library"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
- html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://static.rust-lang.org/doc/master")];
-
-#[feature(macro_rules, globs, asm, managed_boxes, thread_local)];
-
-// Don't link to std. We are std.
-#[no_std];
-
-#[deny(non_camel_case_types)];
-#[deny(missing_doc)];
-
-// When testing libstd, bring in libuv as the I/O backend so tests can print
-// things and all of the std::io tests have an I/O interface to run on top
-// of
-#[cfg(test)] extern mod rustuv(vers = "0.9-pre");
-
-// Make extra accessible for benchmarking
-#[cfg(test)] extern mod extra(vers = "0.9-pre");
-
-// Make std testable by not duplicating lang items. See #2912
-#[cfg(test)] extern mod realstd(name = "std");
-#[cfg(test)] pub use kinds = realstd::kinds;
-#[cfg(test)] pub use ops = realstd::ops;
-#[cfg(test)] pub use cmp = realstd::cmp;
-
-// On Linux, link to the runtime with -lrt.
-#[cfg(target_os = "linux")]
-#[doc(hidden)]
-pub mod linkhack {
- #[link_args="-lrustrt -lrt"]
- #[link_args = "-lpthread"]
- extern {
- }
-}
-
-/* The Prelude. */
-
-pub mod prelude;
-
-
-/* Primitive types */
-
-#[path = "num/int_macros.rs"] mod int_macros;
-#[path = "num/uint_macros.rs"] mod uint_macros;
-
-#[path = "num/int.rs"] pub mod int;
-#[path = "num/i8.rs"] pub mod i8;
-#[path = "num/i16.rs"] pub mod i16;
-#[path = "num/i32.rs"] pub mod i32;
-#[path = "num/i64.rs"] pub mod i64;
-
-#[path = "num/uint.rs"] pub mod uint;
-#[path = "num/u8.rs"] pub mod u8;
-#[path = "num/u16.rs"] pub mod u16;
-#[path = "num/u32.rs"] pub mod u32;
-#[path = "num/u64.rs"] pub mod u64;
-
-#[path = "num/f32.rs"] pub mod f32;
-#[path = "num/f64.rs"] pub mod f64;
-
-pub mod unit;
-pub mod bool;
-pub mod char;
-pub mod tuple;
-
-pub mod vec;
-pub mod at_vec;
-pub mod str;
-
-pub mod ascii;
-pub mod send_str;
-
-pub mod ptr;
-pub mod owned;
-pub mod managed;
-pub mod borrow;
-pub mod rc;
-pub mod gc;
-
-
-/* Core language traits */
-
-#[cfg(not(test))] pub mod kinds;
-#[cfg(not(test))] pub mod ops;
-#[cfg(not(test))] pub mod cmp;
-
-
-/* Common traits */
-
-pub mod from_str;
-pub mod num;
-pub mod iter;
-pub mod to_str;
-pub mod to_bytes;
-pub mod clone;
-pub mod hash;
-pub mod container;
-pub mod default;
-pub mod any;
-
-
-/* Common data structures */
-
-pub mod option;
-pub mod result;
-pub mod either;
-pub mod hashmap;
-pub mod cell;
-pub mod trie;
-
-
-/* Tasks and communication */
-
-pub mod task;
-pub mod comm;
-pub mod select;
-pub mod local_data;
-
-
-/* Runtime and platform support */
-
-pub mod libc;
-pub mod c_str;
-pub mod os;
-pub mod io;
-pub mod path;
-pub mod rand;
-pub mod run;
-pub mod cast;
-pub mod fmt;
-pub mod repr;
-pub mod cleanup;
-pub mod reflect;
-pub mod condition;
-pub mod logging;
-pub mod util;
-pub mod mem;
-
-
-/* Unsupported interfaces */
-
-// Private APIs
-pub mod unstable;
-
-
-/* For internal use, not exported */
-
-mod unicode;
-#[path = "num/cmath.rs"]
-mod cmath;
-
-// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
-// but name resolution doesn't work without it being pub.
-pub mod rt;
-
-// A curious inner-module that's not exported that contains the binding
-// 'std' so that macro-expanded references to std::error and such
-// can be resolved within libstd.
-#[doc(hidden)]
-mod std {
- pub use clone;
- pub use cmp;
- pub use condition;
- pub use fmt;
- pub use kinds;
- pub use local_data;
- pub use logging;
- pub use logging;
- pub use option;
- pub use os;
- pub use io;
- pub use rt;
- pub use str;
- pub use to_bytes;
- pub use to_str;
- pub use unstable;
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-* Bindings for the C standard library and other platform libraries
-*
-* This module contains bindings to the C standard library,
-* organized into modules by their defining standard.
-* Additionally, it contains some assorted platform-specific definitions.
-* For convenience, most functions and types are reexported from `std::libc`,
-* so `pub use std::libc::*` will import the available
-* C bindings as appropriate for the target platform. The exact
-* set of functions available are platform specific.
-*
-* *Note* Because these definitions are platform-specific, some may not appear in
-* the generated documentation.
-*
-* We consider the following specs reasonably normative with respect
-* to interoperating with the C standard library (libc/msvcrt):
-*
-* * ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995.
-* * ISO 9899:1999 ('C99' or 'C9x').
-* * ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1').
-* * ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3').
-* * ISO 9945:2008 / IEEE 1003.1-2008 ('POSIX:2008', 'SUSv4').
-*
-* Note that any reference to the 1996 revision of POSIX, or any revs
-* between 1990 (when '88 was approved at ISO) and 2001 (when the next
-* actual revision-revision happened), are merely additions of other
-* chapters (1b and 1c) outside the core interfaces.
-*
-* Despite having several names each, these are *reasonably* coherent
-* point-in-time, list-of-definition sorts of specs. You can get each under a
-* variety of names but will wind up with the same definition in each case.
-*
-* See standards(7) in linux-manpages for more details.
-*
-* Our interface to these libraries is complicated by the non-universality of
-* conformance to any of them. About the only thing universally supported is
-* the first (C95), beyond that definitions quickly become absent on various
-* platforms.
-*
-* We therefore wind up dividing our module-space up (mostly for the sake of
-* sanity while editing, filling-in-details and eliminating duplication) into
-* definitions common-to-all (held in modules named c95, c99, posix88, posix01
-* and posix08) and definitions that appear only on *some* platforms (named
-* 'extra'). This would be things like significant OSX foundation kit, or
-* win32 library kernel32.dll, or various fancy glibc, linux or BSD
-* extensions.
-*
-* In addition to the per-platform 'extra' modules, we define a module of
-* 'common BSD' libc routines that never quite made it into POSIX but show up
-* in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the
-* final one from Berkeley after the lawsuits died down and the CSRG
-* dissolved.
-*/
-
-#[allow(non_camel_case_types)];
-#[allow(non_uppercase_statics)];
-#[allow(missing_doc)];
-
-// Initial glob-exports mean that all the contents of all the modules
-// wind up exported, if you're interested in writing platform-specific code.
-
-pub use libc::types::common::c95::*;
-pub use libc::types::common::c99::*;
-pub use libc::types::common::posix88::*;
-pub use libc::types::common::posix01::*;
-pub use libc::types::common::posix08::*;
-pub use libc::types::common::bsd44::*;
-pub use libc::types::os::common::posix01::*;
-pub use libc::types::os::arch::c95::*;
-pub use libc::types::os::arch::c99::*;
-pub use libc::types::os::arch::posix88::*;
-pub use libc::types::os::arch::posix01::*;
-pub use libc::types::os::arch::posix08::*;
-pub use libc::types::os::arch::bsd44::*;
-pub use libc::types::os::arch::extra::*;
-
-pub use libc::consts::os::c95::*;
-pub use libc::consts::os::c99::*;
-pub use libc::consts::os::posix88::*;
-pub use libc::consts::os::posix01::*;
-pub use libc::consts::os::posix08::*;
-pub use libc::consts::os::bsd44::*;
-pub use libc::consts::os::extra::*;
-pub use libc::consts::os::sysconf::*;
-
-pub use libc::funcs::c95::ctype::*;
-pub use libc::funcs::c95::stdio::*;
-pub use libc::funcs::c95::stdlib::*;
-pub use libc::funcs::c95::string::*;
-
-pub use libc::funcs::posix88::stat_::*;
-pub use libc::funcs::posix88::stdio::*;
-pub use libc::funcs::posix88::fcntl::*;
-pub use libc::funcs::posix88::dirent::*;
-pub use libc::funcs::posix88::unistd::*;
-pub use libc::funcs::posix88::mman::*;
-
-pub use libc::funcs::posix01::stat_::*;
-pub use libc::funcs::posix01::unistd::*;
-pub use libc::funcs::posix01::glob::*;
-pub use libc::funcs::posix01::mman::*;
-pub use libc::funcs::posix08::unistd::*;
-
-pub use libc::funcs::bsd44::*;
-pub use libc::funcs::extra::*;
-
-#[cfg(target_os = "win32")]
-pub use libc::funcs::extra::kernel32::*;
-#[cfg(target_os = "win32")]
-pub use libc::funcs::extra::msvcrt::*;
-
-// Explicit export lists for the intersection (provided here) mean that
-// you can write more-platform-agnostic code if you stick to just these
-// symbols.
-
-pub use libc::types::common::c95::{FILE, c_void, fpos_t};
-pub use libc::types::common::posix88::{DIR, dirent_t};
-pub use libc::types::os::arch::c95::{c_char, c_double, c_float, c_int};
-pub use libc::types::os::arch::c95::{c_long, c_short, c_uchar, c_ulong};
-pub use libc::types::os::arch::c95::{c_ushort, clock_t, ptrdiff_t};
-pub use libc::types::os::arch::c95::{size_t, time_t};
-pub use libc::types::os::arch::c99::{c_longlong, c_ulonglong, intptr_t};
-pub use libc::types::os::arch::c99::{uintptr_t};
-pub use libc::types::os::arch::posix88::{dev_t, dirent_t, ino_t, mode_t};
-pub use libc::types::os::arch::posix88::{off_t, pid_t, ssize_t};
-
-pub use libc::consts::os::c95::{_IOFBF, _IOLBF, _IONBF, BUFSIZ, EOF};
-pub use libc::consts::os::c95::{EXIT_FAILURE, EXIT_SUCCESS};
-pub use libc::consts::os::c95::{FILENAME_MAX, FOPEN_MAX, L_tmpnam};
-pub use libc::consts::os::c95::{RAND_MAX, SEEK_CUR, SEEK_END};
-pub use libc::consts::os::c95::{SEEK_SET, TMP_MAX};
-pub use libc::consts::os::posix88::{F_OK, O_APPEND, O_CREAT, O_EXCL};
-pub use libc::consts::os::posix88::{O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
-pub use libc::consts::os::posix88::{R_OK, S_IEXEC, S_IFBLK, S_IFCHR};
-pub use libc::consts::os::posix88::{S_IFDIR, S_IFIFO, S_IFMT, S_IFREG, S_IFLNK};
-pub use libc::consts::os::posix88::{S_IREAD, S_IRUSR, S_IRWXU, S_IWUSR};
-pub use libc::consts::os::posix88::{STDERR_FILENO, STDIN_FILENO};
-pub use libc::consts::os::posix88::{STDOUT_FILENO, W_OK, X_OK};
-
-pub use libc::funcs::c95::ctype::{isalnum, isalpha, iscntrl, isdigit};
-pub use libc::funcs::c95::ctype::{islower, isprint, ispunct, isspace};
-pub use libc::funcs::c95::ctype::{isupper, isxdigit, tolower, toupper};
-
-pub use libc::funcs::c95::stdio::{fclose, feof, ferror, fflush, fgetc};
-pub use libc::funcs::c95::stdio::{fgetpos, fgets, fopen, fputc, fputs};
-pub use libc::funcs::c95::stdio::{fread, freopen, fseek, fsetpos, ftell};
-pub use libc::funcs::c95::stdio::{fwrite, perror, puts, remove, rewind};
-pub use libc::funcs::c95::stdio::{setbuf, setvbuf, tmpfile, ungetc};
-
-pub use libc::funcs::c95::stdlib::{abort, abs, atof, atoi, calloc, exit};
-pub use libc::funcs::c95::stdlib::{free, getenv, labs, malloc, rand};
-pub use libc::funcs::c95::stdlib::{realloc, srand, strtod, strtol};
-pub use libc::funcs::c95::stdlib::{strtoul, system};
-
-pub use libc::funcs::c95::string::{memchr, memcmp};
-pub use libc::funcs::c95::string::{strcat, strchr, strcmp};
-pub use libc::funcs::c95::string::{strcoll, strcpy, strcspn, strerror};
-pub use libc::funcs::c95::string::{strlen, strncat, strncmp, strncpy};
-pub use libc::funcs::c95::string::{strpbrk, strrchr, strspn, strstr};
-pub use libc::funcs::c95::string::{strtok, strxfrm};
-
-pub use libc::funcs::posix88::fcntl::{open, creat};
-pub use libc::funcs::posix88::stat_::{chmod, fstat, mkdir, stat};
-pub use libc::funcs::posix88::stdio::{fdopen, fileno, pclose, popen};
-pub use libc::funcs::posix88::unistd::{access, chdir, close, dup, dup2};
-pub use libc::funcs::posix88::unistd::{execv, execve, execvp, getcwd};
-pub use libc::funcs::posix88::unistd::{getpid, isatty, lseek, pipe, read};
-pub use libc::funcs::posix88::unistd::{rmdir, unlink, write};
-
-
-pub mod types {
-
- // Types tend to vary *per architecture* so we pull their definitions out
- // into this module.
-
- // Standard types that are opaque or common, so are not per-target.
- pub mod common {
- pub mod c95 {
- /**
- Type used to construct void pointers for use with C.
-
- This type is only useful as a pointer target. Do not use it as a
- return type for FFI functions which have the `void` return type in
- C. Use the unit type `()` or omit the return type instead.
- */
- pub enum c_void {}
- pub enum FILE {}
- pub enum fpos_t {}
- }
- pub mod c99 {
- pub type int8_t = i8;
- pub type int16_t = i16;
- pub type int32_t = i32;
- pub type int64_t = i64;
- pub type uint8_t = u8;
- pub type uint16_t = u16;
- pub type uint32_t = u32;
- pub type uint64_t = u64;
- }
- pub mod posix88 {
- pub enum DIR {}
- pub enum dirent_t {}
- }
- pub mod posix01 {}
- pub mod posix08 {}
- pub mod bsd44 {}
- }
-
- // Standard types that are scalar but vary by OS and arch.
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- pub mod os {
- pub mod common {
- pub mod posix01 {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{c_char, c_ulong, size_t};
-
- pub type pthread_t = c_ulong;
-
- pub struct glob_t {
- gl_pathc: size_t,
- gl_pathv: **c_char,
- gl_offs: size_t,
-
- __unused1: *c_void,
- __unused2: *c_void,
- __unused3: *c_void,
- __unused4: *c_void,
- __unused5: *c_void,
- }
- }
- }
-
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "arm")]
- #[cfg(target_arch = "mips")]
- pub mod arch {
- pub mod c95 {
- pub type c_char = i8;
- pub type c_schar = i8;
- pub type c_uchar = u8;
- pub type c_short = i16;
- pub type c_ushort = u16;
- pub type c_int = i32;
- pub type c_uint = u32;
- pub type c_long = i32;
- pub type c_ulong = u32;
- pub type c_float = f32;
- pub type c_double = f64;
- pub type size_t = u32;
- pub type ptrdiff_t = i32;
- pub type clock_t = i32;
- pub type time_t = i32;
- pub type wchar_t = i32;
- }
- pub mod c99 {
- pub type c_longlong = i64;
- pub type c_ulonglong = u64;
- pub type intptr_t = int;
- pub type uintptr_t = uint;
- }
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "mips")]
- pub mod posix88 {
- pub type off_t = i32;
- pub type dev_t = u64;
- pub type ino_t = u32;
- pub type pid_t = i32;
- pub type uid_t = u32;
- pub type gid_t = u32;
- pub type useconds_t = u32;
- pub type mode_t = u32;
- pub type ssize_t = i32;
- }
- #[cfg(target_arch = "arm")]
- pub mod posix88 {
- pub type off_t = i32;
- pub type dev_t = u32;
- pub type ino_t = u32;
- pub type pid_t = i32;
- pub type uid_t = u32;
- pub type gid_t = u32;
- pub type useconds_t = u32;
- pub type mode_t = u16;
- pub type ssize_t = i32;
- }
- #[cfg(target_arch = "x86")]
- pub mod posix01 {
- use libc::types::os::arch::c95::{c_short, c_long, time_t};
- use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
- use libc::types::os::arch::posix88::{mode_t, off_t};
- use libc::types::os::arch::posix88::{uid_t};
-
- pub type nlink_t = u32;
- pub type blksize_t = i32;
- pub type blkcnt_t = i32;
-
- pub struct stat {
- st_dev: dev_t,
- __pad1: c_short,
- st_ino: ino_t,
- st_mode: mode_t,
- st_nlink: nlink_t,
- st_uid: uid_t,
- st_gid: gid_t,
- st_rdev: dev_t,
- __pad2: c_short,
- st_size: off_t,
- st_blksize: blksize_t,
- st_blocks: blkcnt_t,
- st_atime: time_t,
- st_atime_nsec: c_long,
- st_mtime: time_t,
- st_mtime_nsec: c_long,
- st_ctime: time_t,
- st_ctime_nsec: c_long,
- __unused4: c_long,
- __unused5: c_long,
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub struct pthread_attr_t {
- __size: [u32, ..9]
- }
- }
- #[cfg(target_arch = "arm")]
- pub mod posix01 {
- use libc::types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t};
- use libc::types::os::arch::c99::{c_longlong, c_ulonglong};
- use libc::types::os::arch::posix88::{uid_t, gid_t, ino_t};
-
- pub type nlink_t = u16;
- pub type blksize_t = u32;
- pub type blkcnt_t = u32;
-
- pub struct stat {
- st_dev: c_ulonglong,
- __pad0: [c_uchar, ..4],
- __st_ino: ino_t,
- st_mode: c_uint,
- st_nlink: c_uint,
- st_uid: uid_t,
- st_gid: gid_t,
- st_rdev: c_ulonglong,
- __pad3: [c_uchar, ..4],
- st_size: c_longlong,
- st_blksize: blksize_t,
- st_blocks: c_ulonglong,
- st_atime: time_t,
- st_atime_nsec: c_ulong,
- st_mtime: time_t,
- st_mtime_nsec: c_ulong,
- st_ctime: time_t,
- st_ctime_nsec: c_ulong,
- st_ino: c_ulonglong
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub struct pthread_attr_t {
- __size: [u32, ..9]
- }
- }
- #[cfg(target_arch = "mips")]
- pub mod posix01 {
- use libc::types::os::arch::c95::{c_long, c_ulong, time_t};
- use libc::types::os::arch::posix88::{gid_t, ino_t};
- use libc::types::os::arch::posix88::{mode_t, off_t};
- use libc::types::os::arch::posix88::{uid_t};
-
- pub type nlink_t = u32;
- pub type blksize_t = i32;
- pub type blkcnt_t = i32;
-
- pub struct stat {
- st_dev: c_ulong,
- st_pad1: [c_long, ..3],
- st_ino: ino_t,
- st_mode: mode_t,
- st_nlink: nlink_t,
- st_uid: uid_t,
- st_gid: gid_t,
- st_rdev: c_ulong,
- st_pad2: [c_long, ..2],
- st_size: off_t,
- st_pad3: c_long,
- st_atime: time_t,
- st_atime_nsec: c_long,
- st_mtime: time_t,
- st_mtime_nsec: c_long,
- st_ctime: time_t,
- st_ctime_nsec: c_long,
- st_blksize: blksize_t,
- st_blocks: blkcnt_t,
- st_pad5: [c_long, ..14],
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub struct pthread_attr_t {
- __size: [u32, ..9]
- }
- }
- pub mod posix08 {}
- pub mod bsd44 {}
- pub mod extra {}
- }
-
- #[cfg(target_arch = "x86_64")]
- pub mod arch {
- pub mod c95 {
- pub type c_char = i8;
- pub type c_schar = i8;
- pub type c_uchar = u8;
- pub type c_short = i16;
- pub type c_ushort = u16;
- pub type c_int = i32;
- pub type c_uint = u32;
- pub type c_long = i64;
- pub type c_ulong = u64;
- pub type c_float = f32;
- pub type c_double = f64;
- pub type size_t = u64;
- pub type ptrdiff_t = i64;
- pub type clock_t = i64;
- pub type time_t = i64;
- pub type wchar_t = i32;
- }
- pub mod c99 {
- pub type c_longlong = i64;
- pub type c_ulonglong = u64;
- pub type intptr_t = int;
- pub type uintptr_t = uint;
- }
- pub mod posix88 {
- pub type off_t = i64;
- pub type dev_t = u64;
- pub type ino_t = u64;
- pub type pid_t = i32;
- pub type uid_t = u32;
- pub type gid_t = u32;
- pub type useconds_t = u32;
- pub type mode_t = u32;
- pub type ssize_t = i64;
- }
- pub mod posix01 {
- use libc::types::os::arch::c95::{c_int, c_long, time_t};
- use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
- use libc::types::os::arch::posix88::{mode_t, off_t};
- use libc::types::os::arch::posix88::{uid_t};
-
- pub type nlink_t = u64;
- pub type blksize_t = i64;
- pub type blkcnt_t = i64;
- pub struct stat {
- st_dev: dev_t,
- st_ino: ino_t,
- st_nlink: nlink_t,
- st_mode: mode_t,
- st_uid: uid_t,
- st_gid: gid_t,
- __pad0: c_int,
- st_rdev: dev_t,
- st_size: off_t,
- st_blksize: blksize_t,
- st_blocks: blkcnt_t,
- st_atime: time_t,
- st_atime_nsec: c_long,
- st_mtime: time_t,
- st_mtime_nsec: c_long,
- st_ctime: time_t,
- st_ctime_nsec: c_long,
- __unused: [c_long, ..3],
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub struct pthread_attr_t {
- __size: [u64, ..7]
- }
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- }
- pub mod extra {
- }
- }
- }
-
- #[cfg(target_os = "freebsd")]
- pub mod os {
- pub mod common {
- pub mod posix01 {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{c_char, c_int, size_t};
- use libc::types::os::arch::c99::{uintptr_t};
-
- pub type pthread_t = uintptr_t;
-
- pub struct glob_t {
- gl_pathc: size_t,
- __unused1: size_t,
- gl_offs: size_t,
- __unused2: c_int,
- gl_pathv: **c_char,
-
- __unused3: *c_void,
-
- __unused4: *c_void,
- __unused5: *c_void,
- __unused6: *c_void,
- __unused7: *c_void,
- __unused8: *c_void,
- }
- }
- }
-
- #[cfg(target_arch = "x86_64")]
- pub mod arch {
- pub mod c95 {
- pub type c_char = i8;
- pub type c_schar = i8;
- pub type c_uchar = u8;
- pub type c_short = i16;
- pub type c_ushort = u16;
- pub type c_int = i32;
- pub type c_uint = u32;
- pub type c_long = i64;
- pub type c_ulong = u64;
- pub type c_float = f32;
- pub type c_double = f64;
- pub type size_t = u64;
- pub type ptrdiff_t = i64;
- pub type clock_t = i32;
- pub type time_t = i64;
- pub type wchar_t = i32;
- }
- pub mod c99 {
- pub type c_longlong = i64;
- pub type c_ulonglong = u64;
- pub type intptr_t = int;
- pub type uintptr_t = uint;
- }
- pub mod posix88 {
- pub type off_t = i64;
- pub type dev_t = u32;
- pub type ino_t = u32;
- pub type pid_t = i32;
- pub type uid_t = u32;
- pub type gid_t = u32;
- pub type useconds_t = u32;
- pub type mode_t = u16;
- pub type ssize_t = i64;
- }
- pub mod posix01 {
- use libc::types::common::c95::{c_void};
- use libc::types::common::c99::{uint8_t, uint32_t, int32_t};
- use libc::types::os::arch::c95::{c_long, time_t};
- use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
- use libc::types::os::arch::posix88::{mode_t, off_t};
- use libc::types::os::arch::posix88::{uid_t};
-
- pub type nlink_t = u16;
- pub type blksize_t = i64;
- pub type blkcnt_t = i64;
- pub type fflags_t = u32;
- pub struct stat {
- st_dev: dev_t,
- st_ino: ino_t,
- st_mode: mode_t,
- st_nlink: nlink_t,
- st_uid: uid_t,
- st_gid: gid_t,
- st_rdev: dev_t,
- st_atime: time_t,
- st_atime_nsec: c_long,
- st_mtime: time_t,
- st_mtime_nsec: c_long,
- st_ctime: time_t,
- st_ctime_nsec: c_long,
- st_size: off_t,
- st_blocks: blkcnt_t,
- st_blksize: blksize_t,
- st_flags: fflags_t,
- st_gen: uint32_t,
- st_lspare: int32_t,
- st_birthtime: time_t,
- st_birthtime_nsec: c_long,
- __unused: [uint8_t, ..2],
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub type pthread_attr_t = *c_void;
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- }
- pub mod extra {
- }
- }
- }
-
- #[cfg(target_os = "win32")]
- pub mod os {
- pub mod common {
- pub mod posix01 {
- use libc::types::os::arch::c95::c_short;
- use libc::types::os::arch::extra::{int64, time64_t};
- use libc::types::os::arch::posix88::{dev_t, ino_t};
- use libc::types::os::arch::posix88::mode_t;
-
- // Note: this is the struct called stat64 in win32. Not stat,
- // nor stati64.
- pub struct stat {
- st_dev: dev_t,
- st_ino: ino_t,
- st_mode: mode_t,
- st_nlink: c_short,
- st_uid: c_short,
- st_gid: c_short,
- st_rdev: dev_t,
- st_size: int64,
- st_atime: time64_t,
- st_mtime: time64_t,
- st_ctime: time64_t,
- }
-
- // note that this is called utimbuf64 in win32
- pub struct utimbuf {
- actime: time64_t,
- modtime: time64_t,
- }
- }
- }
-
- pub mod arch {
- pub mod c95 {
- pub type c_char = i8;
- pub type c_schar = i8;
- pub type c_uchar = u8;
- pub type c_short = i16;
- pub type c_ushort = u16;
- pub type c_int = i32;
- pub type c_uint = u32;
- pub type c_long = i32;
- pub type c_ulong = u32;
- pub type c_float = f32;
- pub type c_double = f64;
-
- #[cfg(target_arch = "x86")]
- pub type size_t = u32;
- #[cfg(target_arch = "x86_64")]
- pub type size_t = u64;
-
- #[cfg(target_arch = "x86")]
- pub type ptrdiff_t = i32;
- #[cfg(target_arch = "x86_64")]
- pub type ptrdiff_t = i64;
-
- pub type clock_t = i32;
-
- #[cfg(target_arch = "x86")]
- pub type time_t = i32;
- #[cfg(target_arch = "x86_64")]
- pub type time_t = i64;
-
- pub type wchar_t = u16;
- }
-
- pub mod c99 {
- pub type c_longlong = i64;
- pub type c_ulonglong = u64;
- pub type intptr_t = int;
- pub type uintptr_t = uint;
- }
-
- pub mod posix88 {
- pub type off_t = i32;
- pub type dev_t = u32;
- pub type ino_t = i16;
-
- #[cfg(target_arch = "x86")]
- pub type pid_t = i32;
- #[cfg(target_arch = "x86_64")]
- pub type pid_t = i64;
-
- pub type useconds_t = u32;
- pub type mode_t = u16;
-
- #[cfg(target_arch = "x86")]
- pub type ssize_t = i32;
- #[cfg(target_arch = "x86_64")]
- pub type ssize_t = i64;
- }
-
- pub mod posix01 {
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- }
- pub mod extra {
- use ptr;
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
- use libc::types::os::arch::c95::{c_long, c_ulong};
- use libc::types::os::arch::c95::{wchar_t};
- use libc::types::os::arch::c99::{c_ulonglong, c_longlong};
-
- pub type BOOL = c_int;
- pub type BYTE = u8;
- pub type CCHAR = c_char;
- pub type CHAR = c_char;
-
- pub type DWORD = c_ulong;
- pub type DWORDLONG = c_ulonglong;
-
- pub type HANDLE = LPVOID;
- pub type HMODULE = c_uint;
-
- pub type LONG = c_long;
- pub type PLONG = *mut c_long;
-
- #[cfg(target_arch = "x86")]
- pub type LONG_PTR = c_long;
- #[cfg(target_arch = "x86_64")]
- pub type LONG_PTR = i64;
-
- pub type LARGE_INTEGER = c_longlong;
- pub type PLARGE_INTEGER = *mut c_longlong;
-
- pub type LPCWSTR = *WCHAR;
- pub type LPCSTR = *CHAR;
-
- pub type LPWSTR = *mut WCHAR;
- pub type LPSTR = *mut CHAR;
-
- pub type LPWCH = *mut WCHAR;
- pub type LPCH = *mut CHAR;
-
- // Not really, but opaque to us.
- pub type LPSECURITY_ATTRIBUTES = LPVOID;
-
- pub type LPVOID = *mut c_void;
- pub type LPCVOID = *c_void;
- pub type LPBYTE = *mut BYTE;
- pub type LPWORD = *mut WORD;
- pub type LPDWORD = *mut DWORD;
- pub type LPHANDLE = *mut HANDLE;
-
- pub type LRESULT = LONG_PTR;
- pub type PBOOL = *mut BOOL;
- pub type WCHAR = wchar_t;
- pub type WORD = u16;
- pub type SIZE_T = size_t;
-
- pub type time64_t = i64;
- pub type int64 = i64;
-
- pub struct STARTUPINFO {
- cb: DWORD,
- lpReserved: LPWSTR,
- lpDesktop: LPWSTR,
- lpTitle: LPWSTR,
- dwX: DWORD,
- dwY: DWORD,
- dwXSize: DWORD,
- dwYSize: DWORD,
- dwXCountChars: DWORD,
- dwYCountCharts: DWORD,
- dwFillAttribute: DWORD,
- dwFlags: DWORD,
- wShowWindow: WORD,
- cbReserved2: WORD,
- lpReserved2: LPBYTE,
- hStdInput: HANDLE,
- hStdOutput: HANDLE,
- hStdError: HANDLE
- }
- pub type LPSTARTUPINFO = *mut STARTUPINFO;
-
- pub struct PROCESS_INFORMATION {
- hProcess: HANDLE,
- hThread: HANDLE,
- dwProcessId: DWORD,
- dwThreadId: DWORD
- }
- pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
-
- pub struct SYSTEM_INFO {
- wProcessorArchitecture: WORD,
- wReserved: WORD,
- dwPageSize: DWORD,
- lpMinimumApplicationAddress: LPVOID,
- lpMaximumApplicationAddress: LPVOID,
- dwActiveProcessorMask: DWORD,
- dwNumberOfProcessors: DWORD,
- dwProcessorType: DWORD,
- dwAllocationGranularity: DWORD,
- wProcessorLevel: WORD,
- wProcessorRevision: WORD
- }
- pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
-
- impl SYSTEM_INFO {
- pub fn new() -> SYSTEM_INFO {
- SYSTEM_INFO {
- wProcessorArchitecture: 0,
- wReserved: 0,
- dwPageSize: 0,
- lpMinimumApplicationAddress: ptr::mut_null(),
- lpMaximumApplicationAddress: ptr::mut_null(),
- dwActiveProcessorMask: 0,
- dwNumberOfProcessors: 0,
- dwProcessorType: 0,
- dwAllocationGranularity: 0,
- wProcessorLevel: 0,
- wProcessorRevision: 0
- }
- }
- }
-
- pub struct MEMORY_BASIC_INFORMATION {
- BaseAddress: LPVOID,
- AllocationBase: LPVOID,
- AllocationProtect: DWORD,
- RegionSize: SIZE_T,
- State: DWORD,
- Protect: DWORD,
- Type: DWORD
- }
- pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
-
- pub struct OVERLAPPED {
- Internal: *c_ulong,
- InternalHigh: *c_ulong,
- Offset: DWORD,
- OffsetHigh: DWORD,
- hEvent: HANDLE,
- }
-
- pub type LPOVERLAPPED = *mut OVERLAPPED;
- }
- }
- }
-
- #[cfg(target_os = "macos")]
- pub mod os {
- pub mod common {
- pub mod posix01 {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{c_char, c_int, size_t};
- use libc::types::os::arch::c99::{uintptr_t};
-
- pub type pthread_t = uintptr_t;
-
- pub struct glob_t {
- gl_pathc: size_t,
- __unused1: c_int,
- gl_offs: size_t,
- __unused2: c_int,
- gl_pathv: **c_char,
-
- __unused3: *c_void,
-
- __unused4: *c_void,
- __unused5: *c_void,
- __unused6: *c_void,
- __unused7: *c_void,
- __unused8: *c_void,
- }
- }
- }
-
- #[cfg(target_arch = "x86")]
- pub mod arch {
- pub mod c95 {
- pub type c_char = i8;
- pub type c_schar = i8;
- pub type c_uchar = u8;
- pub type c_short = i16;
- pub type c_ushort = u16;
- pub type c_int = i32;
- pub type c_uint = u32;
- pub type c_long = i32;
- pub type c_ulong = u32;
- pub type c_float = f32;
- pub type c_double = f64;
- pub type size_t = u32;
- pub type ptrdiff_t = i32;
- pub type clock_t = u32;
- pub type time_t = i32;
- pub type wchar_t = i32;
- }
- pub mod c99 {
- pub type c_longlong = i64;
- pub type c_ulonglong = u64;
- pub type intptr_t = int;
- pub type uintptr_t = uint;
- }
- pub mod posix88 {
- pub type off_t = i64;
- pub type dev_t = i32;
- pub type ino_t = u64;
- pub type pid_t = i32;
- pub type uid_t = u32;
- pub type gid_t = u32;
- pub type useconds_t = u32;
- pub type mode_t = u16;
- pub type ssize_t = i32;
- }
- pub mod posix01 {
- use libc::types::common::c99::{int32_t, int64_t, uint32_t};
- use libc::types::os::arch::c95::{c_char, c_long, time_t};
- use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t,
- mode_t, off_t, uid_t};
-
- pub type nlink_t = u16;
- pub type blksize_t = i64;
- pub type blkcnt_t = i32;
-
- pub struct stat {
- st_dev: dev_t,
- st_mode: mode_t,
- st_nlink: nlink_t,
- st_ino: ino_t,
- st_uid: uid_t,
- st_gid: gid_t,
- st_rdev: dev_t,
- st_atime: time_t,
- st_atime_nsec: c_long,
- st_mtime: time_t,
- st_mtime_nsec: c_long,
- st_ctime: time_t,
- st_ctime_nsec: c_long,
- st_birthtime: time_t,
- st_birthtime_nsec: c_long,
- st_size: off_t,
- st_blocks: blkcnt_t,
- st_blksize: blksize_t,
- st_flags: uint32_t,
- st_gen: uint32_t,
- st_lspare: int32_t,
- st_qspare: [int64_t, ..2],
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub struct pthread_attr_t {
- __sig: c_long,
- __opaque: [c_char, ..36]
- }
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- }
- pub mod extra {
- }
- }
-
- #[cfg(target_arch = "x86_64")]
- pub mod arch {
- pub mod c95 {
- pub type c_char = i8;
- pub type c_schar = i8;
- pub type c_uchar = u8;
- pub type c_short = i16;
- pub type c_ushort = u16;
- pub type c_int = i32;
- pub type c_uint = u32;
- pub type c_long = i64;
- pub type c_ulong = u64;
- pub type c_float = f32;
- pub type c_double = f64;
- pub type size_t = u64;
- pub type ptrdiff_t = i64;
- pub type clock_t = u64;
- pub type time_t = i64;
- pub type wchar_t = i32;
- }
- pub mod c99 {
- pub type c_longlong = i64;
- pub type c_ulonglong = u64;
- pub type intptr_t = int;
- pub type uintptr_t = uint;
- }
- pub mod posix88 {
- pub type off_t = i64;
- pub type dev_t = i32;
- pub type ino_t = u64;
- pub type pid_t = i32;
- pub type uid_t = u32;
- pub type gid_t = u32;
- pub type useconds_t = u32;
- pub type mode_t = u16;
- pub type ssize_t = i64;
- }
- pub mod posix01 {
- use libc::types::common::c99::{int32_t, int64_t};
- use libc::types::common::c99::{uint32_t};
- use libc::types::os::arch::c95::{c_char, c_long, time_t};
- use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
- use libc::types::os::arch::posix88::{mode_t, off_t, uid_t};
-
- pub type nlink_t = u16;
- pub type blksize_t = i64;
- pub type blkcnt_t = i32;
-
- pub struct stat {
- st_dev: dev_t,
- st_mode: mode_t,
- st_nlink: nlink_t,
- st_ino: ino_t,
- st_uid: uid_t,
- st_gid: gid_t,
- st_rdev: dev_t,
- st_atime: time_t,
- st_atime_nsec: c_long,
- st_mtime: time_t,
- st_mtime_nsec: c_long,
- st_ctime: time_t,
- st_ctime_nsec: c_long,
- st_birthtime: time_t,
- st_birthtime_nsec: c_long,
- st_size: off_t,
- st_blocks: blkcnt_t,
- st_blksize: blksize_t,
- st_flags: uint32_t,
- st_gen: uint32_t,
- st_lspare: int32_t,
- st_qspare: [int64_t, ..2],
- }
-
- pub struct utimbuf {
- actime: time_t,
- modtime: time_t,
- }
-
- pub struct pthread_attr_t {
- __sig: c_long,
- __opaque: [c_char, ..56]
- }
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- }
- pub mod extra {
- }
- }
- }
-}
-
-pub mod consts {
- // Consts tend to vary per OS so we pull their definitions out
- // into this module.
-
- #[cfg(target_os = "win32")]
- pub mod os {
- pub mod c95 {
- use libc::types::os::arch::c95::{c_int, c_uint};
-
- pub static EXIT_FAILURE : c_int = 1;
- pub static EXIT_SUCCESS : c_int = 0;
- pub static RAND_MAX : c_int = 32767;
- pub static EOF : c_int = -1;
- pub static SEEK_SET : c_int = 0;
- pub static SEEK_CUR : c_int = 1;
- pub static SEEK_END : c_int = 2;
- pub static _IOFBF : c_int = 0;
- pub static _IONBF : c_int = 4;
- pub static _IOLBF : c_int = 64;
- pub static BUFSIZ : c_uint = 512_u32;
- pub static FOPEN_MAX : c_uint = 20_u32;
- pub static FILENAME_MAX : c_uint = 260_u32;
- pub static L_tmpnam : c_uint = 16_u32;
- pub static TMP_MAX : c_uint = 32767_u32;
- }
- pub mod c99 {
- }
- pub mod posix88 {
- use libc::types::os::arch::c95::c_int;
-
- pub static O_RDONLY : c_int = 0;
- pub static O_WRONLY : c_int = 1;
- pub static O_RDWR : c_int = 2;
- pub static O_APPEND : c_int = 8;
- pub static O_CREAT : c_int = 256;
- pub static O_EXCL : c_int = 1024;
- pub static O_TRUNC : c_int = 512;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 12288;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
- pub static F_OK : c_int = 0;
- pub static R_OK : c_int = 4;
- pub static W_OK : c_int = 2;
- pub static X_OK : c_int = 1;
- pub static STDIN_FILENO : c_int = 0;
- pub static STDOUT_FILENO : c_int = 1;
- pub static STDERR_FILENO : c_int = 2;
- }
- pub mod posix01 {
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- }
- pub mod extra {
- use libc::types::os::arch::c95::c_int;
- use libc::types::os::arch::extra::{WORD, DWORD, BOOL};
-
- pub static TRUE : BOOL = 1;
- pub static FALSE : BOOL = 0;
-
- pub static O_TEXT : c_int = 16384;
- pub static O_BINARY : c_int = 32768;
- pub static O_NOINHERIT: c_int = 128;
-
- pub static ERROR_SUCCESS : c_int = 0;
- pub static ERROR_INVALID_HANDLE : c_int = 6;
- pub static ERROR_DISK_FULL : c_int = 112;
- pub static ERROR_INSUFFICIENT_BUFFER : c_int = 122;
- pub static ERROR_ALREADY_EXISTS : c_int = 183;
- pub static ERROR_INVALID_ADDRESS : c_int = 487;
- pub static ERROR_FILE_INVALID : c_int = 1006;
- pub static INVALID_HANDLE_VALUE : c_int = -1;
-
- pub static DELETE : DWORD = 0x00010000;
- pub static READ_CONTROL : DWORD = 0x00020000;
- pub static SYNCHRONIZE : DWORD = 0x00100000;
- pub static WRITE_DAC : DWORD = 0x00040000;
- pub static WRITE_OWNER : DWORD = 0x00080000;
-
- pub static PROCESS_CREATE_PROCESS : DWORD = 0x0080;
- pub static PROCESS_CREATE_THREAD : DWORD = 0x0002;
- pub static PROCESS_DUP_HANDLE : DWORD = 0x0040;
- pub static PROCESS_QUERY_INFORMATION : DWORD = 0x0400;
- pub static PROCESS_QUERY_LIMITED_INFORMATION : DWORD = 0x1000;
- pub static PROCESS_SET_INFORMATION : DWORD = 0x0200;
- pub static PROCESS_SET_QUOTA : DWORD = 0x0100;
- pub static PROCESS_SUSPEND_RESUME : DWORD = 0x0800;
- pub static PROCESS_TERMINATE : DWORD = 0x0001;
- pub static PROCESS_VM_OPERATION : DWORD = 0x0008;
- pub static PROCESS_VM_READ : DWORD = 0x0010;
- pub static PROCESS_VM_WRITE : DWORD = 0x0020;
-
- pub static STARTF_FORCEONFEEDBACK : DWORD = 0x00000040;
- pub static STARTF_FORCEOFFFEEDBACK : DWORD = 0x00000080;
- pub static STARTF_PREVENTPINNING : DWORD = 0x00002000;
- pub static STARTF_RUNFULLSCREEN : DWORD = 0x00000020;
- pub static STARTF_TITLEISAPPID : DWORD = 0x00001000;
- pub static STARTF_TITLEISLINKNAME : DWORD = 0x00000800;
- pub static STARTF_USECOUNTCHARS : DWORD = 0x00000008;
- pub static STARTF_USEFILLATTRIBUTE : DWORD = 0x00000010;
- pub static STARTF_USEHOTKEY : DWORD = 0x00000200;
- pub static STARTF_USEPOSITION : DWORD = 0x00000004;
- pub static STARTF_USESHOWWINDOW : DWORD = 0x00000001;
- pub static STARTF_USESIZE : DWORD = 0x00000002;
- pub static STARTF_USESTDHANDLES : DWORD = 0x00000100;
-
- pub static WAIT_ABANDONED : DWORD = 0x00000080;
- pub static WAIT_OBJECT_0 : DWORD = 0x00000000;
- pub static WAIT_TIMEOUT : DWORD = 0x00000102;
- pub static WAIT_FAILED : DWORD = -1;
-
- pub static DUPLICATE_CLOSE_SOURCE : DWORD = 0x00000001;
- pub static DUPLICATE_SAME_ACCESS : DWORD = 0x00000002;
-
- pub static INFINITE : DWORD = -1;
- pub static STILL_ACTIVE : DWORD = 259;
-
- pub static MEM_COMMIT : DWORD = 0x00001000;
- pub static MEM_RESERVE : DWORD = 0x00002000;
- pub static MEM_DECOMMIT : DWORD = 0x00004000;
- pub static MEM_RELEASE : DWORD = 0x00008000;
- pub static MEM_RESET : DWORD = 0x00080000;
- pub static MEM_RESET_UNDO : DWORD = 0x1000000;
- pub static MEM_LARGE_PAGES : DWORD = 0x20000000;
- pub static MEM_PHYSICAL : DWORD = 0x00400000;
- pub static MEM_TOP_DOWN : DWORD = 0x00100000;
- pub static MEM_WRITE_WATCH : DWORD = 0x00200000;
-
- pub static PAGE_EXECUTE : DWORD = 0x10;
- pub static PAGE_EXECUTE_READ : DWORD = 0x20;
- pub static PAGE_EXECUTE_READWRITE : DWORD = 0x40;
- pub static PAGE_EXECUTE_WRITECOPY : DWORD = 0x80;
- pub static PAGE_NOACCESS : DWORD = 0x01;
- pub static PAGE_READONLY : DWORD = 0x02;
- pub static PAGE_READWRITE : DWORD = 0x04;
- pub static PAGE_WRITECOPY : DWORD = 0x08;
- pub static PAGE_GUARD : DWORD = 0x100;
- pub static PAGE_NOCACHE : DWORD = 0x200;
- pub static PAGE_WRITECOMBINE : DWORD = 0x400;
-
- pub static SEC_COMMIT : DWORD = 0x8000000;
- pub static SEC_IMAGE : DWORD = 0x1000000;
- pub static SEC_IMAGE_NO_EXECUTE : DWORD = 0x11000000;
- pub static SEC_LARGE_PAGES : DWORD = 0x80000000;
- pub static SEC_NOCACHE : DWORD = 0x10000000;
- pub static SEC_RESERVE : DWORD = 0x4000000;
- pub static SEC_WRITECOMBINE : DWORD = 0x40000000;
-
- pub static FILE_MAP_ALL_ACCESS : DWORD = 0xf001f;
- pub static FILE_MAP_READ : DWORD = 0x4;
- pub static FILE_MAP_WRITE : DWORD = 0x2;
- pub static FILE_MAP_COPY : DWORD = 0x1;
- pub static FILE_MAP_EXECUTE : DWORD = 0x20;
-
- pub static PROCESSOR_ARCHITECTURE_INTEL : WORD = 0;
- pub static PROCESSOR_ARCHITECTURE_ARM : WORD = 5;
- pub static PROCESSOR_ARCHITECTURE_IA64 : WORD = 6;
- pub static PROCESSOR_ARCHITECTURE_AMD64 : WORD = 9;
- pub static PROCESSOR_ARCHITECTURE_UNKNOWN : WORD = 0xffff;
-
- pub static MOVEFILE_COPY_ALLOWED: DWORD = 2;
- pub static MOVEFILE_CREATE_HARDLINK: DWORD = 16;
- pub static MOVEFILE_DELAY_UNTIL_REBOOT: DWORD = 4;
- pub static MOVEFILE_FAIL_IF_NOT_TRACKABLE: DWORD = 32;
- pub static MOVEFILE_REPLACE_EXISTING: DWORD = 1;
- pub static MOVEFILE_WRITE_THROUGH: DWORD = 8;
-
- pub static SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 1;
-
- pub static FILE_SHARE_DELETE: DWORD = 0x4;
- pub static FILE_SHARE_READ: DWORD = 0x1;
- pub static FILE_SHARE_WRITE: DWORD = 0x2;
-
- pub static CREATE_ALWAYS: DWORD = 2;
- pub static CREATE_NEW: DWORD = 1;
- pub static OPEN_ALWAYS: DWORD = 4;
- pub static OPEN_EXISTING: DWORD = 3;
- pub static TRUNCATE_EXISTING: DWORD = 5;
-
- pub static FILE_ATTRIBUTE_ARCHIVE: DWORD = 0x20;
- pub static FILE_ATTRIBUTE_COMPRESSED: DWORD = 0x800;
- pub static FILE_ATTRIBUTE_DEVICE: DWORD = 0x40;
- pub static FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
- pub static FILE_ATTRIBUTE_ENCRYPTED: DWORD = 0x4000;
- pub static FILE_ATTRIBUTE_HIDDEN: DWORD = 0x2;
- pub static FILE_ATTRIBUTE_INTEGRITY_STREAM: DWORD = 0x8000;
- pub static FILE_ATTRIBUTE_NORMAL: DWORD = 0x80;
- pub static FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: DWORD = 0x2000;
- pub static FILE_ATTRIBUTE_NO_SCRUB_DATA: DWORD = 0x20000;
- pub static FILE_ATTRIBUTE_OFFLINE: DWORD = 0x1000;
- pub static FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
- pub static FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
- pub static FILE_ATTRIBUTE_SPARSE_FILE: DWORD = 0x200;
- pub static FILE_ATTRIBUTE_SYSTEM: DWORD = 0x4;
- pub static FILE_ATTRIBUTE_TEMPORARY: DWORD = 0x100;
- pub static FILE_ATTRIBUTE_VIRTUAL: DWORD = 0x10000;
-
- pub static FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
- pub static FILE_FLAG_DELETE_ON_CLOSE: DWORD = 0x04000000;
- pub static FILE_FLAG_NO_BUFFERING: DWORD = 0x20000000;
- pub static FILE_FLAG_OPEN_NO_RECALL: DWORD = 0x00100000;
- pub static FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
- pub static FILE_FLAG_OVERLAPPED: DWORD = 0x40000000;
- pub static FILE_FLAG_POSIX_SEMANTICS: DWORD = 0x0100000;
- pub static FILE_FLAG_RANDOM_ACCESS: DWORD = 0x10000000;
- pub static FILE_FLAG_SESSION_AWARE: DWORD = 0x00800000;
- pub static FILE_FLAG_SEQUENTIAL_SCAN: DWORD = 0x08000000;
- pub static FILE_FLAG_WRITE_THROUGH: DWORD = 0x80000000;
-
- pub static FILE_NAME_NORMALIZED: DWORD = 0x0;
- pub static FILE_NAME_OPENED: DWORD = 0x8;
-
- pub static VOLUME_NAME_DOS: DWORD = 0x0;
- pub static VOLUME_NAME_GUID: DWORD = 0x1;
- pub static VOLUME_NAME_NONE: DWORD = 0x4;
- pub static VOLUME_NAME_NT: DWORD = 0x2;
-
- pub static GENERIC_READ: DWORD = 0x80000000;
- pub static GENERIC_WRITE: DWORD = 0x40000000;
- pub static GENERIC_EXECUTE: DWORD = 0x20000000;
- pub static GENERIC_ALL: DWORD = 0x10000000;
-
- pub static FILE_BEGIN: DWORD = 0;
- pub static FILE_CURRENT: DWORD = 1;
- pub static FILE_END: DWORD = 2;
- }
- pub mod sysconf {
- }
- }
-
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- pub mod os {
- pub mod c95 {
- use libc::types::os::arch::c95::{c_int, c_uint};
-
- pub static EXIT_FAILURE : c_int = 1;
- pub static EXIT_SUCCESS : c_int = 0;
- pub static RAND_MAX : c_int = 2147483647;
- pub static EOF : c_int = -1;
- pub static SEEK_SET : c_int = 0;
- pub static SEEK_CUR : c_int = 1;
- pub static SEEK_END : c_int = 2;
- pub static _IOFBF : c_int = 0;
- pub static _IONBF : c_int = 2;
- pub static _IOLBF : c_int = 1;
- pub static BUFSIZ : c_uint = 8192_u32;
- pub static FOPEN_MAX : c_uint = 16_u32;
- pub static FILENAME_MAX : c_uint = 4096_u32;
- pub static L_tmpnam : c_uint = 20_u32;
- pub static TMP_MAX : c_uint = 238328_u32;
- }
- pub mod c99 {
- }
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "x86_64")]
- #[cfg(target_arch = "arm")]
- pub mod posix88 {
- use libc::types::os::arch::c95::c_int;
- use libc::types::common::c95::c_void;
-
- pub static O_RDONLY : c_int = 0;
- pub static O_WRONLY : c_int = 1;
- pub static O_RDWR : c_int = 2;
- pub static O_APPEND : c_int = 1024;
- pub static O_CREAT : c_int = 64;
- pub static O_EXCL : c_int = 128;
- pub static O_TRUNC : c_int = 512;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
- pub static F_OK : c_int = 0;
- pub static R_OK : c_int = 4;
- pub static W_OK : c_int = 2;
- pub static X_OK : c_int = 1;
- pub static STDIN_FILENO : c_int = 0;
- pub static STDOUT_FILENO : c_int = 1;
- pub static STDERR_FILENO : c_int = 2;
- pub static F_LOCK : c_int = 1;
- pub static F_TEST : c_int = 3;
- pub static F_TLOCK : c_int = 2;
- pub static F_ULOCK : c_int = 0;
- pub static SIGHUP : c_int = 1;
- pub static SIGINT : c_int = 2;
- pub static SIGQUIT : c_int = 3;
- pub static SIGILL : c_int = 4;
- pub static SIGABRT : c_int = 6;
- pub static SIGFPE : c_int = 8;
- pub static SIGKILL : c_int = 9;
- pub static SIGSEGV : c_int = 11;
- pub static SIGPIPE : c_int = 13;
- pub static SIGALRM : c_int = 14;
- pub static SIGTERM : c_int = 15;
-
- pub static PROT_NONE : c_int = 0;
- pub static PROT_READ : c_int = 1;
- pub static PROT_WRITE : c_int = 2;
- pub static PROT_EXEC : c_int = 4;
-
- pub static MAP_FILE : c_int = 0x0000;
- pub static MAP_SHARED : c_int = 0x0001;
- pub static MAP_PRIVATE : c_int = 0x0002;
- pub static MAP_FIXED : c_int = 0x0010;
- pub static MAP_ANON : c_int = 0x0020;
-
- pub static MAP_FAILED : *c_void = -1 as *c_void;
-
- pub static MCL_CURRENT : c_int = 0x0001;
- pub static MCL_FUTURE : c_int = 0x0002;
-
- pub static MS_ASYNC : c_int = 0x0001;
- pub static MS_INVALIDATE : c_int = 0x0002;
- pub static MS_SYNC : c_int = 0x0004;
-
- pub static EPERM : c_int = 1;
- pub static ENOENT : c_int = 2;
- pub static ESRCH : c_int = 3;
- pub static EINTR : c_int = 4;
- pub static EIO : c_int = 5;
- pub static ENXIO : c_int = 6;
- pub static E2BIG : c_int = 7;
- pub static ENOEXEC : c_int = 8;
- pub static EBADF : c_int = 9;
- pub static ECHILD : c_int = 10;
- pub static EAGAIN : c_int = 11;
- pub static ENOMEM : c_int = 12;
- pub static EACCES : c_int = 13;
- pub static EFAULT : c_int = 14;
- pub static ENOTBLK : c_int = 15;
- pub static EBUSY : c_int = 16;
- pub static EEXIST : c_int = 17;
- pub static EXDEV : c_int = 18;
- pub static ENODEV : c_int = 19;
- pub static ENOTDIR : c_int = 20;
- pub static EISDIR : c_int = 21;
- pub static EINVAL : c_int = 22;
- pub static ENFILE : c_int = 23;
- pub static EMFILE : c_int = 24;
- pub static ENOTTY : c_int = 25;
- pub static ETXTBSY : c_int = 26;
- pub static EFBIG : c_int = 27;
- pub static ENOSPC : c_int = 28;
- pub static ESPIPE : c_int = 29;
- pub static EROFS : c_int = 30;
- pub static EMLINK : c_int = 31;
- pub static EPIPE : c_int = 32;
- pub static EDOM : c_int = 33;
- pub static ERANGE : c_int = 34;
-
- pub static EDEADLK: c_int = 35;
- pub static ENAMETOOLONG: c_int = 36;
- pub static ENOLCK: c_int = 37;
- pub static ENOSYS: c_int = 38;
- pub static ENOTEMPTY: c_int = 39;
- pub static ELOOP: c_int = 40;
- pub static EWOULDBLOCK: c_int = EAGAIN;
- pub static ENOMSG: c_int = 42;
- pub static EIDRM: c_int = 43;
- pub static ECHRNG: c_int = 44;
- pub static EL2NSYNC: c_int = 45;
- pub static EL3HLT: c_int = 46;
- pub static EL3RST: c_int = 47;
- pub static ELNRNG: c_int = 48;
- pub static EUNATCH: c_int = 49;
- pub static ENOCSI: c_int = 50;
- pub static EL2HLT: c_int = 51;
- pub static EBADE: c_int = 52;
- pub static EBADR: c_int = 53;
- pub static EXFULL: c_int = 54;
- pub static ENOANO: c_int = 55;
- pub static EBADRQC: c_int = 56;
- pub static EBADSLT: c_int = 57;
-
- pub static EDEADLOCK: c_int = EDEADLK;
-
- pub static EBFONT: c_int = 59;
- pub static ENOSTR: c_int = 60;
- pub static ENODATA: c_int = 61;
- pub static ETIME: c_int = 62;
- pub static ENOSR: c_int = 63;
- pub static ENONET: c_int = 64;
- pub static ENOPKG: c_int = 65;
- pub static EREMOTE: c_int = 66;
- pub static ENOLINK: c_int = 67;
- pub static EADV: c_int = 68;
- pub static ESRMNT: c_int = 69;
- pub static ECOMM: c_int = 70;
- pub static EPROTO: c_int = 71;
- pub static EMULTIHOP: c_int = 72;
- pub static EDOTDOT: c_int = 73;
- pub static EBADMSG: c_int = 74;
- pub static EOVERFLOW: c_int = 75;
- pub static ENOTUNIQ: c_int = 76;
- pub static EBADFD: c_int = 77;
- pub static EREMCHG: c_int = 78;
- pub static ELIBACC: c_int = 79;
- pub static ELIBBAD: c_int = 80;
- pub static ELIBSCN: c_int = 81;
- pub static ELIBMAX: c_int = 82;
- pub static ELIBEXEC: c_int = 83;
- pub static EILSEQ: c_int = 84;
- pub static ERESTART: c_int = 85;
- pub static ESTRPIPE: c_int = 86;
- pub static EUSERS: c_int = 87;
- pub static ENOTSOCK: c_int = 88;
- pub static EDESTADDRREQ: c_int = 89;
- pub static EMSGSIZE: c_int = 90;
- pub static EPROTOTYPE: c_int = 91;
- pub static ENOPROTOOPT: c_int = 92;
- pub static EPROTONOSUPPORT: c_int = 93;
- pub static ESOCKTNOSUPPORT: c_int = 94;
- pub static EOPNOTSUPP: c_int = 95;
- pub static EPFNOSUPPORT: c_int = 96;
- pub static EAFNOSUPPORT: c_int = 97;
- pub static EADDRINUSE: c_int = 98;
- pub static EADDRNOTAVAIL: c_int = 99;
- pub static ENETDOWN: c_int = 100;
- pub static ENETUNREACH: c_int = 101;
- pub static ENETRESET: c_int = 102;
- pub static ECONNABORTED: c_int = 103;
- pub static ECONNRESET: c_int = 104;
- pub static ENOBUFS: c_int = 105;
- pub static EISCONN: c_int = 106;
- pub static ENOTCONN: c_int = 107;
- pub static ESHUTDOWN: c_int = 108;
- pub static ETOOMANYREFS: c_int = 109;
- pub static ETIMEDOUT: c_int = 110;
- pub static ECONNREFUSED: c_int = 111;
- pub static EHOSTDOWN: c_int = 112;
- pub static EHOSTUNREACH: c_int = 113;
- pub static EALREADY: c_int = 114;
- pub static EINPROGRESS: c_int = 115;
- pub static ESTALE: c_int = 116;
- pub static EUCLEAN: c_int = 117;
- pub static ENOTNAM: c_int = 118;
- pub static ENAVAIL: c_int = 119;
- pub static EISNAM: c_int = 120;
- pub static EREMOTEIO: c_int = 121;
- pub static EDQUOT: c_int = 122;
-
- pub static ENOMEDIUM: c_int = 123;
- pub static EMEDIUMTYPE: c_int = 124;
- pub static ECANCELED: c_int = 125;
- pub static ENOKEY: c_int = 126;
- pub static EKEYEXPIRED: c_int = 127;
- pub static EKEYREVOKED: c_int = 128;
- pub static EKEYREJECTED: c_int = 129;
-
- pub static EOWNERDEAD: c_int = 130;
- pub static ENOTRECOVERABLE: c_int = 131;
-
- pub static ERFKILL: c_int = 132;
-
- pub static EHWPOISON: c_int = 133;
- }
-
- #[cfg(target_arch = "mips")]
- pub mod posix88 {
- use libc::types::os::arch::c95::c_int;
- use libc::types::common::c95::c_void;
-
- pub static O_RDONLY : c_int = 0;
- pub static O_WRONLY : c_int = 1;
- pub static O_RDWR : c_int = 2;
- pub static O_APPEND : c_int = 8;
- pub static O_CREAT : c_int = 256;
- pub static O_EXCL : c_int = 1024;
- pub static O_TRUNC : c_int = 512;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
- pub static F_OK : c_int = 0;
- pub static R_OK : c_int = 4;
- pub static W_OK : c_int = 2;
- pub static X_OK : c_int = 1;
- pub static STDIN_FILENO : c_int = 0;
- pub static STDOUT_FILENO : c_int = 1;
- pub static STDERR_FILENO : c_int = 2;
- pub static F_LOCK : c_int = 1;
- pub static F_TEST : c_int = 3;
- pub static F_TLOCK : c_int = 2;
- pub static F_ULOCK : c_int = 0;
- pub static SIGHUP : c_int = 1;
- pub static SIGINT : c_int = 2;
- pub static SIGQUIT : c_int = 3;
- pub static SIGILL : c_int = 4;
- pub static SIGABRT : c_int = 6;
- pub static SIGFPE : c_int = 8;
- pub static SIGKILL : c_int = 9;
- pub static SIGSEGV : c_int = 11;
- pub static SIGPIPE : c_int = 13;
- pub static SIGALRM : c_int = 14;
- pub static SIGTERM : c_int = 15;
-
- pub static PROT_NONE : c_int = 0;
- pub static PROT_READ : c_int = 1;
- pub static PROT_WRITE : c_int = 2;
- pub static PROT_EXEC : c_int = 4;
-
- pub static MAP_FILE : c_int = 0x0000;
- pub static MAP_SHARED : c_int = 0x0001;
- pub static MAP_PRIVATE : c_int = 0x0002;
- pub static MAP_FIXED : c_int = 0x0010;
- pub static MAP_ANON : c_int = 0x0020;
-
- pub static MAP_FAILED : *c_void = -1 as *c_void;
-
- pub static MCL_CURRENT : c_int = 0x0001;
- pub static MCL_FUTURE : c_int = 0x0002;
-
- pub static MS_ASYNC : c_int = 0x0001;
- pub static MS_INVALIDATE : c_int = 0x0002;
- pub static MS_SYNC : c_int = 0x0004;
-
- pub static EPERM : c_int = 1;
- pub static ENOENT : c_int = 2;
- pub static ESRCH : c_int = 3;
- pub static EINTR : c_int = 4;
- pub static EIO : c_int = 5;
- pub static ENXIO : c_int = 6;
- pub static E2BIG : c_int = 7;
- pub static ENOEXEC : c_int = 8;
- pub static EBADF : c_int = 9;
- pub static ECHILD : c_int = 10;
- pub static EAGAIN : c_int = 11;
- pub static ENOMEM : c_int = 12;
- pub static EACCES : c_int = 13;
- pub static EFAULT : c_int = 14;
- pub static ENOTBLK : c_int = 15;
- pub static EBUSY : c_int = 16;
- pub static EEXIST : c_int = 17;
- pub static EXDEV : c_int = 18;
- pub static ENODEV : c_int = 19;
- pub static ENOTDIR : c_int = 20;
- pub static EISDIR : c_int = 21;
- pub static EINVAL : c_int = 22;
- pub static ENFILE : c_int = 23;
- pub static EMFILE : c_int = 24;
- pub static ENOTTY : c_int = 25;
- pub static ETXTBSY : c_int = 26;
- pub static EFBIG : c_int = 27;
- pub static ENOSPC : c_int = 28;
- pub static ESPIPE : c_int = 29;
- pub static EROFS : c_int = 30;
- pub static EMLINK : c_int = 31;
- pub static EPIPE : c_int = 32;
- pub static EDOM : c_int = 33;
- pub static ERANGE : c_int = 34;
-
- pub static ENOMSG: c_int = 35;
- pub static EIDRM: c_int = 36;
- pub static ECHRNG: c_int = 37;
- pub static EL2NSYNC: c_int = 38;
- pub static EL3HLT: c_int = 39;
- pub static EL3RST: c_int = 40;
- pub static ELNRNG: c_int = 41;
- pub static EUNATCH: c_int = 42;
- pub static ENOCSI: c_int = 43;
- pub static EL2HLT: c_int = 44;
- pub static EDEADLK: c_int = 45;
- pub static ENOLCK: c_int = 46;
- pub static EBADE: c_int = 50;
- pub static EBADR: c_int = 51;
- pub static EXFULL: c_int = 52;
- pub static ENOANO: c_int = 53;
- pub static EBADRQC: c_int = 54;
- pub static EBADSLT: c_int = 55;
- pub static EDEADLOCK: c_int = 56;
- pub static EBFONT: c_int = 59;
- pub static ENOSTR: c_int = 60;
- pub static ENODATA: c_int = 61;
- pub static ETIME: c_int = 62;
- pub static ENOSR: c_int = 63;
- pub static ENONET: c_int = 64;
- pub static ENOPKG: c_int = 65;
- pub static EREMOTE: c_int = 66;
- pub static ENOLINK: c_int = 67;
- pub static EADV: c_int = 68;
- pub static ESRMNT: c_int = 69;
- pub static ECOMM: c_int = 70;
- pub static EPROTO: c_int = 71;
- pub static EDOTDOT: c_int = 73;
- pub static EMULTIHOP: c_int = 74;
- pub static EBADMSG: c_int = 77;
- pub static ENAMETOOLONG: c_int = 78;
- pub static EOVERFLOW: c_int = 79;
- pub static ENOTUNIQ: c_int = 80;
- pub static EBADFD: c_int = 81;
- pub static EREMCHG: c_int = 82;
- pub static ELIBACC: c_int = 83;
- pub static ELIBBAD: c_int = 84;
- pub static ELIBSCN: c_int = 95;
- pub static ELIBMAX: c_int = 86;
- pub static ELIBEXEC: c_int = 87;
- pub static EILSEQ: c_int = 88;
- pub static ENOSYS: c_int = 89;
- pub static ELOOP: c_int = 90;
- pub static ERESTART: c_int = 91;
- pub static ESTRPIPE: c_int = 92;
- pub static ENOTEMPTY: c_int = 93;
- pub static EUSERS: c_int = 94;
- pub static ENOTSOCK: c_int = 95;
- pub static EDESTADDRREQ: c_int = 96;
- pub static EMSGSIZE: c_int = 97;
- pub static EPROTOTYPE: c_int = 98;
- pub static ENOPROTOOPT: c_int = 99;
- pub static EPROTONOSUPPORT: c_int = 120;
- pub static ESOCKTNOSUPPORT: c_int = 121;
- pub static EOPNOTSUPP: c_int = 122;
- pub static EPFNOSUPPORT: c_int = 123;
- pub static EAFNOSUPPORT: c_int = 124;
- pub static EADDRINUSE: c_int = 125;
- pub static EADDRNOTAVAIL: c_int = 126;
- pub static ENETDOWN: c_int = 127;
- pub static ENETUNREACH: c_int = 128;
- pub static ENETRESET: c_int = 129;
- pub static ECONNABORTED: c_int = 130;
- pub static ECONNRESET: c_int = 131;
- pub static ENOBUFS: c_int = 132;
- pub static EISCONN: c_int = 133;
- pub static ENOTCONN: c_int = 134;
- pub static EUCLEAN: c_int = 135;
- pub static ENOTNAM: c_int = 137;
- pub static ENAVAIL: c_int = 138;
- pub static EISNAM: c_int = 139;
- pub static EREMOTEIO: c_int = 140;
- pub static ESHUTDOWN: c_int = 143;
- pub static ETOOMANYREFS: c_int = 144;
- pub static ETIMEDOUT: c_int = 145;
- pub static ECONNREFUSED: c_int = 146;
- pub static EHOSTDOWN: c_int = 147;
- pub static EHOSTUNREACH: c_int = 148;
- pub static EWOULDBLOCK: c_int = EAGAIN;
- pub static EALREADY: c_int = 149;
- pub static EINPROGRESS: c_int = 150;
- pub static ESTALE: c_int = 151;
- pub static ECANCELED: c_int = 158;
-
- pub static ENOMEDIUM: c_int = 159;
- pub static EMEDIUMTYPE: c_int = 160;
- pub static ENOKEY: c_int = 161;
- pub static EKEYEXPIRED: c_int = 162;
- pub static EKEYREVOKED: c_int = 163;
- pub static EKEYREJECTED: c_int = 164;
-
- pub static EOWNERDEAD: c_int = 165;
- pub static ENOTRECOVERABLE: c_int = 166;
-
- pub static ERFKILL: c_int = 167;
-
- pub static EHWPOISON: c_int = 168;
-
- pub static EDQUOT: c_int = 1133;
- }
- pub mod posix01 {
- use libc::types::os::arch::c95::c_int;
-
- pub static SIGTRAP : c_int = 5;
-
- pub static GLOB_ERR : c_int = 1 << 0;
- pub static GLOB_MARK : c_int = 1 << 1;
- pub static GLOB_NOSORT : c_int = 1 << 2;
- pub static GLOB_DOOFFS : c_int = 1 << 3;
- pub static GLOB_NOCHECK : c_int = 1 << 4;
- pub static GLOB_APPEND : c_int = 1 << 5;
- pub static GLOB_NOESCAPE : c_int = 1 << 6;
-
- pub static GLOB_NOSPACE : c_int = 1;
- pub static GLOB_ABORTED : c_int = 2;
- pub static GLOB_NOMATCH : c_int = 3;
-
- pub static POSIX_MADV_NORMAL : c_int = 0;
- pub static POSIX_MADV_RANDOM : c_int = 1;
- pub static POSIX_MADV_SEQUENTIAL : c_int = 2;
- pub static POSIX_MADV_WILLNEED : c_int = 3;
- pub static POSIX_MADV_DONTNEED : c_int = 4;
-
- pub static _SC_MQ_PRIO_MAX : c_int = 28;
- pub static _SC_IOV_MAX : c_int = 60;
- pub static _SC_GETGR_R_SIZE_MAX : c_int = 69;
- pub static _SC_GETPW_R_SIZE_MAX : c_int = 70;
- pub static _SC_LOGIN_NAME_MAX : c_int = 71;
- pub static _SC_TTY_NAME_MAX : c_int = 72;
- pub static _SC_THREADS : c_int = 67;
- pub static _SC_THREAD_SAFE_FUNCTIONS : c_int = 68;
- pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 73;
- pub static _SC_THREAD_KEYS_MAX : c_int = 74;
- pub static _SC_THREAD_STACK_MIN : c_int = 75;
- pub static _SC_THREAD_THREADS_MAX : c_int = 76;
- pub static _SC_THREAD_ATTR_STACKADDR : c_int = 77;
- pub static _SC_THREAD_ATTR_STACKSIZE : c_int = 78;
- pub static _SC_THREAD_PRIORITY_SCHEDULING : c_int = 79;
- pub static _SC_THREAD_PRIO_INHERIT : c_int = 80;
- pub static _SC_THREAD_PRIO_PROTECT : c_int = 81;
- pub static _SC_THREAD_PROCESS_SHARED : c_int = 82;
- pub static _SC_ATEXIT_MAX : c_int = 87;
- pub static _SC_XOPEN_VERSION : c_int = 89;
- pub static _SC_XOPEN_XCU_VERSION : c_int = 90;
- pub static _SC_XOPEN_UNIX : c_int = 91;
- pub static _SC_XOPEN_CRYPT : c_int = 92;
- pub static _SC_XOPEN_ENH_I18N : c_int = 93;
- pub static _SC_XOPEN_SHM : c_int = 94;
- pub static _SC_XOPEN_LEGACY : c_int = 129;
- pub static _SC_XOPEN_REALTIME : c_int = 130;
- pub static _SC_XOPEN_REALTIME_THREADS : c_int = 131;
-
- pub static PTHREAD_CREATE_JOINABLE: c_int = 0;
- pub static PTHREAD_CREATE_DETACHED: c_int = 1;
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- use libc::types::os::arch::c95::c_int;
-
- pub static MADV_NORMAL : c_int = 0;
- pub static MADV_RANDOM : c_int = 1;
- pub static MADV_SEQUENTIAL : c_int = 2;
- pub static MADV_WILLNEED : c_int = 3;
- pub static MADV_DONTNEED : c_int = 4;
- pub static MADV_REMOVE : c_int = 9;
- pub static MADV_DONTFORK : c_int = 10;
- pub static MADV_DOFORK : c_int = 11;
- pub static MADV_MERGEABLE : c_int = 12;
- pub static MADV_UNMERGEABLE : c_int = 13;
- pub static MADV_HWPOISON : c_int = 100;
- }
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "x86_64")]
- #[cfg(target_arch = "arm")]
- pub mod extra {
- use libc::types::os::arch::c95::c_int;
-
- pub static O_RSYNC : c_int = 1052672;
- pub static O_DSYNC : c_int = 4096;
- pub static O_SYNC : c_int = 1052672;
-
- pub static PROT_GROWSDOWN : c_int = 0x010000000;
- pub static PROT_GROWSUP : c_int = 0x020000000;
-
- pub static MAP_TYPE : c_int = 0x000f;
- pub static MAP_ANONONYMOUS : c_int = 0x0020;
- pub static MAP_32BIT : c_int = 0x0040;
- pub static MAP_GROWSDOWN : c_int = 0x0100;
- pub static MAP_DENYWRITE : c_int = 0x0800;
- pub static MAP_EXECUTABLE : c_int = 0x01000;
- pub static MAP_LOCKED : c_int = 0x02000;
- pub static MAP_NONRESERVE : c_int = 0x04000;
- pub static MAP_POPULATE : c_int = 0x08000;
- pub static MAP_NONBLOCK : c_int = 0x010000;
- pub static MAP_STACK : c_int = 0x020000;
- }
- #[cfg(target_arch = "mips")]
- pub mod extra {
- use libc::types::os::arch::c95::c_int;
-
- pub static O_RSYNC : c_int = 16400;
- pub static O_DSYNC : c_int = 16;
- pub static O_SYNC : c_int = 16400;
-
- pub static PROT_GROWSDOWN : c_int = 0x010000000;
- pub static PROT_GROWSUP : c_int = 0x020000000;
-
- pub static MAP_TYPE : c_int = 0x000f;
- pub static MAP_ANONONYMOUS : c_int = 0x0020;
- pub static MAP_32BIT : c_int = 0x0040;
- pub static MAP_GROWSDOWN : c_int = 0x0100;
- pub static MAP_DENYWRITE : c_int = 0x0800;
- pub static MAP_EXECUTABLE : c_int = 0x01000;
- pub static MAP_LOCKED : c_int = 0x02000;
- pub static MAP_NONRESERVE : c_int = 0x04000;
- pub static MAP_POPULATE : c_int = 0x08000;
- pub static MAP_NONBLOCK : c_int = 0x010000;
- pub static MAP_STACK : c_int = 0x020000;
- }
- #[cfg(target_os = "linux")]
- pub mod sysconf {
- use libc::types::os::arch::c95::c_int;
-
- pub static _SC_ARG_MAX : c_int = 0;
- pub static _SC_CHILD_MAX : c_int = 1;
- pub static _SC_CLK_TCK : c_int = 2;
- pub static _SC_NGROUPS_MAX : c_int = 3;
- pub static _SC_OPEN_MAX : c_int = 4;
- pub static _SC_STREAM_MAX : c_int = 5;
- pub static _SC_TZNAME_MAX : c_int = 6;
- pub static _SC_JOB_CONTROL : c_int = 7;
- pub static _SC_SAVED_IDS : c_int = 8;
- pub static _SC_REALTIME_SIGNALS : c_int = 9;
- pub static _SC_PRIORITY_SCHEDULING : c_int = 10;
- pub static _SC_TIMERS : c_int = 11;
- pub static _SC_ASYNCHRONOUS_IO : c_int = 12;
- pub static _SC_PRIORITIZED_IO : c_int = 13;
- pub static _SC_SYNCHRONIZED_IO : c_int = 14;
- pub static _SC_FSYNC : c_int = 15;
- pub static _SC_MAPPED_FILES : c_int = 16;
- pub static _SC_MEMLOCK : c_int = 17;
- pub static _SC_MEMLOCK_RANGE : c_int = 18;
- pub static _SC_MEMORY_PROTECTION : c_int = 19;
- pub static _SC_MESSAGE_PASSING : c_int = 20;
- pub static _SC_SEMAPHORES : c_int = 21;
- pub static _SC_SHARED_MEMORY_OBJECTS : c_int = 22;
- pub static _SC_AIO_LISTIO_MAX : c_int = 23;
- pub static _SC_AIO_MAX : c_int = 24;
- pub static _SC_AIO_PRIO_DELTA_MAX : c_int = 25;
- pub static _SC_DELAYTIMER_MAX : c_int = 26;
- pub static _SC_MQ_OPEN_MAX : c_int = 27;
- pub static _SC_VERSION : c_int = 29;
- pub static _SC_PAGESIZE : c_int = 30;
- pub static _SC_RTSIG_MAX : c_int = 31;
- pub static _SC_SEM_NSEMS_MAX : c_int = 32;
- pub static _SC_SEM_VALUE_MAX : c_int = 33;
- pub static _SC_SIGQUEUE_MAX : c_int = 34;
- pub static _SC_TIMER_MAX : c_int = 35;
- pub static _SC_BC_BASE_MAX : c_int = 36;
- pub static _SC_BC_DIM_MAX : c_int = 37;
- pub static _SC_BC_SCALE_MAX : c_int = 38;
- pub static _SC_BC_STRING_MAX : c_int = 39;
- pub static _SC_COLL_WEIGHTS_MAX : c_int = 40;
- pub static _SC_EXPR_NEST_MAX : c_int = 42;
- pub static _SC_LINE_MAX : c_int = 43;
- pub static _SC_RE_DUP_MAX : c_int = 44;
- pub static _SC_2_VERSION : c_int = 46;
- pub static _SC_2_C_BIND : c_int = 47;
- pub static _SC_2_C_DEV : c_int = 48;
- pub static _SC_2_FORT_DEV : c_int = 49;
- pub static _SC_2_FORT_RUN : c_int = 50;
- pub static _SC_2_SW_DEV : c_int = 51;
- pub static _SC_2_LOCALEDEF : c_int = 52;
- pub static _SC_2_CHAR_TERM : c_int = 95;
- pub static _SC_2_C_VERSION : c_int = 96;
- pub static _SC_2_UPE : c_int = 97;
- pub static _SC_XBS5_ILP32_OFF32 : c_int = 125;
- pub static _SC_XBS5_ILP32_OFFBIG : c_int = 126;
- pub static _SC_XBS5_LPBIG_OFFBIG : c_int = 128;
- }
- #[cfg(target_os = "android")]
- pub mod sysconf {
- use libc::types::os::arch::c95::c_int;
-
- pub static _SC_ARG_MAX : c_int = 0;
- pub static _SC_BC_BASE_MAX : c_int = 1;
- pub static _SC_BC_DIM_MAX : c_int = 2;
- pub static _SC_BC_SCALE_MAX : c_int = 3;
- pub static _SC_BC_STRING_MAX : c_int = 4;
- pub static _SC_CHILD_MAX : c_int = 5;
- pub static _SC_CLK_TCK : c_int = 6;
- pub static _SC_COLL_WEIGHTS_MAX : c_int = 7;
- pub static _SC_EXPR_NEST_MAX : c_int = 8;
- pub static _SC_LINE_MAX : c_int = 9;
- pub static _SC_NGROUPS_MAX : c_int = 10;
- pub static _SC_OPEN_MAX : c_int = 11;
- pub static _SC_2_C_BIND : c_int = 13;
- pub static _SC_2_C_DEV : c_int = 14;
- pub static _SC_2_C_VERSION : c_int = 15;
- pub static _SC_2_CHAR_TERM : c_int = 16;
- pub static _SC_2_FORT_DEV : c_int = 17;
- pub static _SC_2_FORT_RUN : c_int = 18;
- pub static _SC_2_LOCALEDEF : c_int = 19;
- pub static _SC_2_SW_DEV : c_int = 20;
- pub static _SC_2_UPE : c_int = 21;
- pub static _SC_2_VERSION : c_int = 22;
- pub static _SC_JOB_CONTROL : c_int = 23;
- pub static _SC_SAVED_IDS : c_int = 24;
- pub static _SC_VERSION : c_int = 25;
- pub static _SC_RE_DUP_MAX : c_int = 26;
- pub static _SC_STREAM_MAX : c_int = 27;
- pub static _SC_TZNAME_MAX : c_int = 28;
- pub static _SC_PAGESIZE : c_int = 39;
- }
- }
-
- #[cfg(target_os = "freebsd")]
- pub mod os {
- pub mod c95 {
- use libc::types::os::arch::c95::{c_int, c_uint};
-
- pub static EXIT_FAILURE : c_int = 1;
- pub static EXIT_SUCCESS : c_int = 0;
- pub static RAND_MAX : c_int = 2147483647;
- pub static EOF : c_int = -1;
- pub static SEEK_SET : c_int = 0;
- pub static SEEK_CUR : c_int = 1;
- pub static SEEK_END : c_int = 2;
- pub static _IOFBF : c_int = 0;
- pub static _IONBF : c_int = 2;
- pub static _IOLBF : c_int = 1;
- pub static BUFSIZ : c_uint = 1024_u32;
- pub static FOPEN_MAX : c_uint = 20_u32;
- pub static FILENAME_MAX : c_uint = 1024_u32;
- pub static L_tmpnam : c_uint = 1024_u32;
- pub static TMP_MAX : c_uint = 308915776_u32;
- }
- pub mod c99 {
- }
- pub mod posix88 {
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::c_int;
-
- pub static O_RDONLY : c_int = 0;
- pub static O_WRONLY : c_int = 1;
- pub static O_RDWR : c_int = 2;
- pub static O_APPEND : c_int = 8;
- pub static O_CREAT : c_int = 512;
- pub static O_EXCL : c_int = 2048;
- pub static O_TRUNC : c_int = 1024;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
- pub static F_OK : c_int = 0;
- pub static R_OK : c_int = 4;
- pub static W_OK : c_int = 2;
- pub static X_OK : c_int = 1;
- pub static STDIN_FILENO : c_int = 0;
- pub static STDOUT_FILENO : c_int = 1;
- pub static STDERR_FILENO : c_int = 2;
- pub static F_LOCK : c_int = 1;
- pub static F_TEST : c_int = 3;
- pub static F_TLOCK : c_int = 2;
- pub static F_ULOCK : c_int = 0;
- pub static SIGHUP : c_int = 1;
- pub static SIGINT : c_int = 2;
- pub static SIGQUIT : c_int = 3;
- pub static SIGILL : c_int = 4;
- pub static SIGABRT : c_int = 6;
- pub static SIGFPE : c_int = 8;
- pub static SIGKILL : c_int = 9;
- pub static SIGSEGV : c_int = 11;
- pub static SIGPIPE : c_int = 13;
- pub static SIGALRM : c_int = 14;
- pub static SIGTERM : c_int = 15;
-
- pub static PROT_NONE : c_int = 0;
- pub static PROT_READ : c_int = 1;
- pub static PROT_WRITE : c_int = 2;
- pub static PROT_EXEC : c_int = 4;
-
- pub static MAP_FILE : c_int = 0x0000;
- pub static MAP_SHARED : c_int = 0x0001;
- pub static MAP_PRIVATE : c_int = 0x0002;
- pub static MAP_FIXED : c_int = 0x0010;
- pub static MAP_ANON : c_int = 0x1000;
-
- pub static MAP_FAILED : *c_void = -1 as *c_void;
-
- pub static MCL_CURRENT : c_int = 0x0001;
- pub static MCL_FUTURE : c_int = 0x0002;
-
- pub static MS_SYNC : c_int = 0x0000;
- pub static MS_ASYNC : c_int = 0x0001;
- pub static MS_INVALIDATE : c_int = 0x0002;
-
- pub static EPERM : c_int = 1;
- pub static ENOENT : c_int = 2;
- pub static ESRCH : c_int = 3;
- pub static EINTR : c_int = 4;
- pub static EIO : c_int = 5;
- pub static ENXIO : c_int = 6;
- pub static E2BIG : c_int = 7;
- pub static ENOEXEC : c_int = 8;
- pub static EBADF : c_int = 9;
- pub static ECHILD : c_int = 10;
- pub static EDEADLK : c_int = 11;
- pub static ENOMEM : c_int = 12;
- pub static EACCES : c_int = 13;
- pub static EFAULT : c_int = 14;
- pub static ENOTBLK : c_int = 15;
- pub static EBUSY : c_int = 16;
- pub static EEXIST : c_int = 17;
- pub static EXDEV : c_int = 18;
- pub static ENODEV : c_int = 19;
- pub static ENOTDIR : c_int = 20;
- pub static EISDIR : c_int = 21;
- pub static EINVAL : c_int = 22;
- pub static ENFILE : c_int = 23;
- pub static EMFILE : c_int = 24;
- pub static ENOTTY : c_int = 25;
- pub static ETXTBSY : c_int = 26;
- pub static EFBIG : c_int = 27;
- pub static ENOSPC : c_int = 28;
- pub static ESPIPE : c_int = 29;
- pub static EROFS : c_int = 30;
- pub static EMLINK : c_int = 31;
- pub static EPIPE : c_int = 32;
- pub static EDOM : c_int = 33;
- pub static ERANGE : c_int = 34;
- pub static EAGAIN : c_int = 35;
- pub static EWOULDBLOCK : c_int = 35;
- pub static EINPROGRESS : c_int = 36;
- pub static EALREADY : c_int = 37;
- pub static ENOTSOCK : c_int = 38;
- pub static EDESTADDRREQ : c_int = 39;
- pub static EMSGSIZE : c_int = 40;
- pub static EPROTOTYPE : c_int = 41;
- pub static ENOPROTOOPT : c_int = 42;
- pub static EPROTONOSUPPORT : c_int = 43;
- pub static ESOCKTNOSUPPORT : c_int = 44;
- pub static EOPNOTSUPP : c_int = 45;
- pub static EPFNOSUPPORT : c_int = 46;
- pub static EAFNOSUPPORT : c_int = 47;
- pub static EADDRINUSE : c_int = 48;
- pub static EADDRNOTAVAIL : c_int = 49;
- pub static ENETDOWN : c_int = 50;
- pub static ENETUNREACH : c_int = 51;
- pub static ENETRESET : c_int = 52;
- pub static ECONNABORTED : c_int = 53;
- pub static ECONNRESET : c_int = 54;
- pub static ENOBUFS : c_int = 55;
- pub static EISCONN : c_int = 56;
- pub static ENOTCONN : c_int = 57;
- pub static ESHUTDOWN : c_int = 58;
- pub static ETOOMANYREFS : c_int = 59;
- pub static ETIMEDOUT : c_int = 60;
- pub static ECONNREFUSED : c_int = 61;
- pub static ELOOP : c_int = 62;
- pub static ENAMETOOLONG : c_int = 63;
- pub static EHOSTDOWN : c_int = 64;
- pub static EHOSTUNREACH : c_int = 65;
- pub static ENOTEMPTY : c_int = 66;
- pub static EPROCLIM : c_int = 67;
- pub static EUSERS : c_int = 68;
- pub static EDQUOT : c_int = 69;
- pub static ESTALE : c_int = 70;
- pub static EREMOTE : c_int = 71;
- pub static EBADRPC : c_int = 72;
- pub static ERPCMISMATCH : c_int = 73;
- pub static EPROGUNAVAIL : c_int = 74;
- pub static EPROGMISMATCH : c_int = 75;
- pub static EPROCUNAVAIL : c_int = 76;
- pub static ENOLCK : c_int = 77;
- pub static ENOSYS : c_int = 78;
- pub static EFTYPE : c_int = 79;
- pub static EAUTH : c_int = 80;
- pub static ENEEDAUTH : c_int = 81;
- pub static EIDRM : c_int = 82;
- pub static ENOMSG : c_int = 83;
- pub static EOVERFLOW : c_int = 84;
- pub static ECANCELED : c_int = 85;
- pub static EILSEQ : c_int = 86;
- pub static ENOATTR : c_int = 87;
- pub static EDOOFUS : c_int = 88;
- pub static EBADMSG : c_int = 89;
- pub static EMULTIHOP : c_int = 90;
- pub static ENOLINK : c_int = 91;
- pub static EPROTO : c_int = 92;
- pub static ENOMEDIUM : c_int = 93;
- pub static EUNUSED94 : c_int = 94;
- pub static EUNUSED95 : c_int = 95;
- pub static EUNUSED96 : c_int = 96;
- pub static EUNUSED97 : c_int = 97;
- pub static EUNUSED98 : c_int = 98;
- pub static EASYNC : c_int = 99;
- pub static ELAST : c_int = 99;
- }
- pub mod posix01 {
- use libc::types::os::arch::c95::c_int;
-
- pub static SIGTRAP : c_int = 5;
-
- pub static GLOB_APPEND : c_int = 0x0001;
- pub static GLOB_DOOFFS : c_int = 0x0002;
- pub static GLOB_ERR : c_int = 0x0004;
- pub static GLOB_MARK : c_int = 0x0008;
- pub static GLOB_NOCHECK : c_int = 0x0010;
- pub static GLOB_NOSORT : c_int = 0x0020;
- pub static GLOB_NOESCAPE : c_int = 0x2000;
-
- pub static GLOB_NOSPACE : c_int = -1;
- pub static GLOB_ABORTED : c_int = -2;
- pub static GLOB_NOMATCH : c_int = -3;
-
- pub static POSIX_MADV_NORMAL : c_int = 0;
- pub static POSIX_MADV_RANDOM : c_int = 1;
- pub static POSIX_MADV_SEQUENTIAL : c_int = 2;
- pub static POSIX_MADV_WILLNEED : c_int = 3;
- pub static POSIX_MADV_DONTNEED : c_int = 4;
-
- pub static _SC_IOV_MAX : c_int = 56;
- pub static _SC_GETGR_R_SIZE_MAX : c_int = 70;
- pub static _SC_GETPW_R_SIZE_MAX : c_int = 71;
- pub static _SC_LOGIN_NAME_MAX : c_int = 73;
- pub static _SC_MQ_PRIO_MAX : c_int = 75;
- pub static _SC_THREAD_ATTR_STACKADDR : c_int = 82;
- pub static _SC_THREAD_ATTR_STACKSIZE : c_int = 83;
- pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 85;
- pub static _SC_THREAD_KEYS_MAX : c_int = 86;
- pub static _SC_THREAD_PRIO_INHERIT : c_int = 87;
- pub static _SC_THREAD_PRIO_PROTECT : c_int = 88;
- pub static _SC_THREAD_PRIORITY_SCHEDULING : c_int = 89;
- pub static _SC_THREAD_PROCESS_SHARED : c_int = 90;
- pub static _SC_THREAD_SAFE_FUNCTIONS : c_int = 91;
- pub static _SC_THREAD_STACK_MIN : c_int = 93;
- pub static _SC_THREAD_THREADS_MAX : c_int = 94;
- pub static _SC_THREADS : c_int = 96;
- pub static _SC_TTY_NAME_MAX : c_int = 101;
- pub static _SC_ATEXIT_MAX : c_int = 107;
- pub static _SC_XOPEN_CRYPT : c_int = 108;
- pub static _SC_XOPEN_ENH_I18N : c_int = 109;
- pub static _SC_XOPEN_LEGACY : c_int = 110;
- pub static _SC_XOPEN_REALTIME : c_int = 111;
- pub static _SC_XOPEN_REALTIME_THREADS : c_int = 112;
- pub static _SC_XOPEN_SHM : c_int = 113;
- pub static _SC_XOPEN_UNIX : c_int = 115;
- pub static _SC_XOPEN_VERSION : c_int = 116;
- pub static _SC_XOPEN_XCU_VERSION : c_int = 117;
-
- pub static PTHREAD_CREATE_JOINABLE: c_int = 0;
- pub static PTHREAD_CREATE_DETACHED: c_int = 1;
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- use libc::types::os::arch::c95::c_int;
-
- pub static MADV_NORMAL : c_int = 0;
- pub static MADV_RANDOM : c_int = 1;
- pub static MADV_SEQUENTIAL : c_int = 2;
- pub static MADV_WILLNEED : c_int = 3;
- pub static MADV_DONTNEED : c_int = 4;
- pub static MADV_FREE : c_int = 5;
- pub static MADV_NOSYNC : c_int = 6;
- pub static MADV_AUTOSYNC : c_int = 7;
- pub static MADV_NOCORE : c_int = 8;
- pub static MADV_CORE : c_int = 9;
- pub static MADV_PROTECT : c_int = 10;
-
- pub static MINCORE_INCORE : c_int = 0x1;
- pub static MINCORE_REFERENCED : c_int = 0x2;
- pub static MINCORE_MODIFIED : c_int = 0x4;
- pub static MINCORE_REFERENCED_OTHER : c_int = 0x8;
- pub static MINCORE_MODIFIED_OTHER : c_int = 0x10;
- pub static MINCORE_SUPER : c_int = 0x20;
- }
- pub mod extra {
- use libc::types::os::arch::c95::c_int;
-
- pub static O_SYNC : c_int = 128;
- pub static CTL_KERN: c_int = 1;
- pub static KERN_PROC: c_int = 14;
- pub static KERN_PROC_PATHNAME: c_int = 12;
-
- pub static MAP_COPY : c_int = 0x0002;
- pub static MAP_RENAME : c_int = 0x0020;
- pub static MAP_NORESERVE : c_int = 0x0040;
- pub static MAP_HASSEMAPHORE : c_int = 0x0200;
- pub static MAP_STACK : c_int = 0x0400;
- pub static MAP_NOSYNC : c_int = 0x0800;
- pub static MAP_NOCORE : c_int = 0x020000;
- }
- pub mod sysconf {
- use libc::types::os::arch::c95::c_int;
-
- pub static _SC_ARG_MAX : c_int = 1;
- pub static _SC_CHILD_MAX : c_int = 2;
- pub static _SC_CLK_TCK : c_int = 3;
- pub static _SC_NGROUPS_MAX : c_int = 4;
- pub static _SC_OPEN_MAX : c_int = 5;
- pub static _SC_JOB_CONTROL : c_int = 6;
- pub static _SC_SAVED_IDS : c_int = 7;
- pub static _SC_VERSION : c_int = 8;
- pub static _SC_BC_BASE_MAX : c_int = 9;
- pub static _SC_BC_DIM_MAX : c_int = 10;
- pub static _SC_BC_SCALE_MAX : c_int = 11;
- pub static _SC_BC_STRING_MAX : c_int = 12;
- pub static _SC_COLL_WEIGHTS_MAX : c_int = 13;
- pub static _SC_EXPR_NEST_MAX : c_int = 14;
- pub static _SC_LINE_MAX : c_int = 15;
- pub static _SC_RE_DUP_MAX : c_int = 16;
- pub static _SC_2_VERSION : c_int = 17;
- pub static _SC_2_C_BIND : c_int = 18;
- pub static _SC_2_C_DEV : c_int = 19;
- pub static _SC_2_CHAR_TERM : c_int = 20;
- pub static _SC_2_FORT_DEV : c_int = 21;
- pub static _SC_2_FORT_RUN : c_int = 22;
- pub static _SC_2_LOCALEDEF : c_int = 23;
- pub static _SC_2_SW_DEV : c_int = 24;
- pub static _SC_2_UPE : c_int = 25;
- pub static _SC_STREAM_MAX : c_int = 26;
- pub static _SC_TZNAME_MAX : c_int = 27;
- pub static _SC_ASYNCHRONOUS_IO : c_int = 28;
- pub static _SC_MAPPED_FILES : c_int = 29;
- pub static _SC_MEMLOCK : c_int = 30;
- pub static _SC_MEMLOCK_RANGE : c_int = 31;
- pub static _SC_MEMORY_PROTECTION : c_int = 32;
- pub static _SC_MESSAGE_PASSING : c_int = 33;
- pub static _SC_PRIORITIZED_IO : c_int = 34;
- pub static _SC_PRIORITY_SCHEDULING : c_int = 35;
- pub static _SC_REALTIME_SIGNALS : c_int = 36;
- pub static _SC_SEMAPHORES : c_int = 37;
- pub static _SC_FSYNC : c_int = 38;
- pub static _SC_SHARED_MEMORY_OBJECTS : c_int = 39;
- pub static _SC_SYNCHRONIZED_IO : c_int = 40;
- pub static _SC_TIMERS : c_int = 41;
- pub static _SC_AIO_LISTIO_MAX : c_int = 42;
- pub static _SC_AIO_MAX : c_int = 43;
- pub static _SC_AIO_PRIO_DELTA_MAX : c_int = 44;
- pub static _SC_DELAYTIMER_MAX : c_int = 45;
- pub static _SC_MQ_OPEN_MAX : c_int = 46;
- pub static _SC_PAGESIZE : c_int = 47;
- pub static _SC_RTSIG_MAX : c_int = 48;
- pub static _SC_SEM_NSEMS_MAX : c_int = 49;
- pub static _SC_SEM_VALUE_MAX : c_int = 50;
- pub static _SC_SIGQUEUE_MAX : c_int = 51;
- pub static _SC_TIMER_MAX : c_int = 52;
- }
- }
-
- #[cfg(target_os = "macos")]
- pub mod os {
- pub mod c95 {
- use libc::types::os::arch::c95::{c_int, c_uint};
-
- pub static EXIT_FAILURE : c_int = 1;
- pub static EXIT_SUCCESS : c_int = 0;
- pub static RAND_MAX : c_int = 2147483647;
- pub static EOF : c_int = -1;
- pub static SEEK_SET : c_int = 0;
- pub static SEEK_CUR : c_int = 1;
- pub static SEEK_END : c_int = 2;
- pub static _IOFBF : c_int = 0;
- pub static _IONBF : c_int = 2;
- pub static _IOLBF : c_int = 1;
- pub static BUFSIZ : c_uint = 1024_u32;
- pub static FOPEN_MAX : c_uint = 20_u32;
- pub static FILENAME_MAX : c_uint = 1024_u32;
- pub static L_tmpnam : c_uint = 1024_u32;
- pub static TMP_MAX : c_uint = 308915776_u32;
- }
- pub mod c99 {
- }
- pub mod posix88 {
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::c_int;
-
- pub static O_RDONLY : c_int = 0;
- pub static O_WRONLY : c_int = 1;
- pub static O_RDWR : c_int = 2;
- pub static O_APPEND : c_int = 8;
- pub static O_CREAT : c_int = 512;
- pub static O_EXCL : c_int = 2048;
- pub static O_TRUNC : c_int = 1024;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
- pub static F_OK : c_int = 0;
- pub static R_OK : c_int = 4;
- pub static W_OK : c_int = 2;
- pub static X_OK : c_int = 1;
- pub static STDIN_FILENO : c_int = 0;
- pub static STDOUT_FILENO : c_int = 1;
- pub static STDERR_FILENO : c_int = 2;
- pub static F_LOCK : c_int = 1;
- pub static F_TEST : c_int = 3;
- pub static F_TLOCK : c_int = 2;
- pub static F_ULOCK : c_int = 0;
- pub static SIGHUP : c_int = 1;
- pub static SIGINT : c_int = 2;
- pub static SIGQUIT : c_int = 3;
- pub static SIGILL : c_int = 4;
- pub static SIGABRT : c_int = 6;
- pub static SIGFPE : c_int = 8;
- pub static SIGKILL : c_int = 9;
- pub static SIGSEGV : c_int = 11;
- pub static SIGPIPE : c_int = 13;
- pub static SIGALRM : c_int = 14;
- pub static SIGTERM : c_int = 15;
-
- pub static PROT_NONE : c_int = 0;
- pub static PROT_READ : c_int = 1;
- pub static PROT_WRITE : c_int = 2;
- pub static PROT_EXEC : c_int = 4;
-
- pub static MAP_FILE : c_int = 0x0000;
- pub static MAP_SHARED : c_int = 0x0001;
- pub static MAP_PRIVATE : c_int = 0x0002;
- pub static MAP_FIXED : c_int = 0x0010;
- pub static MAP_ANON : c_int = 0x1000;
-
- pub static MAP_FAILED : *c_void = -1 as *c_void;
-
- pub static MCL_CURRENT : c_int = 0x0001;
- pub static MCL_FUTURE : c_int = 0x0002;
-
- pub static MS_ASYNC : c_int = 0x0001;
- pub static MS_INVALIDATE : c_int = 0x0002;
- pub static MS_SYNC : c_int = 0x0010;
-
- pub static MS_KILLPAGES : c_int = 0x0004;
- pub static MS_DEACTIVATE : c_int = 0x0008;
-
- pub static EPERM : c_int = 1;
- pub static ENOENT : c_int = 2;
- pub static ESRCH : c_int = 3;
- pub static EINTR : c_int = 4;
- pub static EIO : c_int = 5;
- pub static ENXIO : c_int = 6;
- pub static E2BIG : c_int = 7;
- pub static ENOEXEC : c_int = 8;
- pub static EBADF : c_int = 9;
- pub static ECHILD : c_int = 10;
- pub static EDEADLK : c_int = 11;
- pub static ENOMEM : c_int = 12;
- pub static EACCES : c_int = 13;
- pub static EFAULT : c_int = 14;
- pub static ENOTBLK : c_int = 15;
- pub static EBUSY : c_int = 16;
- pub static EEXIST : c_int = 17;
- pub static EXDEV : c_int = 18;
- pub static ENODEV : c_int = 19;
- pub static ENOTDIR : c_int = 20;
- pub static EISDIR : c_int = 21;
- pub static EINVAL : c_int = 22;
- pub static ENFILE : c_int = 23;
- pub static EMFILE : c_int = 24;
- pub static ENOTTY : c_int = 25;
- pub static ETXTBSY : c_int = 26;
- pub static EFBIG : c_int = 27;
- pub static ENOSPC : c_int = 28;
- pub static ESPIPE : c_int = 29;
- pub static EROFS : c_int = 30;
- pub static EMLINK : c_int = 31;
- pub static EPIPE : c_int = 32;
- pub static EDOM : c_int = 33;
- pub static ERANGE : c_int = 34;
- pub static EAGAIN : c_int = 35;
- pub static EWOULDBLOCK : c_int = EAGAIN;
- pub static EINPROGRESS : c_int = 36;
- pub static EALREADY : c_int = 37;
- pub static ENOTSOCK : c_int = 38;
- pub static EDESTADDRREQ : c_int = 39;
- pub static EMSGSIZE : c_int = 40;
- pub static EPROTOTYPE : c_int = 41;
- pub static ENOPROTOOPT : c_int = 42;
- pub static EPROTONOSUPPORT : c_int = 43;
- pub static ESOCKTNOSUPPORT : c_int = 44;
- pub static ENOTSUP : c_int = 45;
- pub static EPFNOSUPPORT : c_int = 46;
- pub static EAFNOSUPPORT : c_int = 47;
- pub static EADDRINUSE : c_int = 48;
- pub static EADDRNOTAVAIL : c_int = 49;
- pub static ENETDOWN : c_int = 50;
- pub static ENETUNREACH : c_int = 51;
- pub static ENETRESET : c_int = 52;
- pub static ECONNABORTED : c_int = 53;
- pub static ECONNRESET : c_int = 54;
- pub static ENOBUFS : c_int = 55;
- pub static EISCONN : c_int = 56;
- pub static ENOTCONN : c_int = 57;
- pub static ESHUTDOWN : c_int = 58;
- pub static ETOOMANYREFS : c_int = 59;
- pub static ETIMEDOUT : c_int = 60;
- pub static ECONNREFUSED : c_int = 61;
- pub static ELOOP : c_int = 62;
- pub static ENAMETOOLONG : c_int = 63;
- pub static EHOSTDOWN : c_int = 64;
- pub static EHOSTUNREACH : c_int = 65;
- pub static ENOTEMPTY : c_int = 66;
- pub static EPROCLIM : c_int = 67;
- pub static EUSERS : c_int = 68;
- pub static EDQUOT : c_int = 69;
- pub static ESTALE : c_int = 70;
- pub static EREMOTE : c_int = 71;
- pub static EBADRPC : c_int = 72;
- pub static ERPCMISMATCH : c_int = 73;
- pub static EPROGUNAVAIL : c_int = 74;
- pub static EPROGMISMATCH : c_int = 75;
- pub static EPROCUNAVAIL : c_int = 76;
- pub static ENOLCK : c_int = 77;
- pub static ENOSYS : c_int = 78;
- pub static EFTYPE : c_int = 79;
- pub static EAUTH : c_int = 80;
- pub static ENEEDAUTH : c_int = 81;
- pub static EPWROFF : c_int = 82;
- pub static EDEVERR : c_int = 83;
- pub static EOVERFLOW : c_int = 84;
- pub static EBADEXEC : c_int = 85;
- pub static EBADARCH : c_int = 86;
- pub static ESHLIBVERS : c_int = 87;
- pub static EBADMACHO : c_int = 88;
- pub static ECANCELED : c_int = 89;
- pub static EIDRM : c_int = 90;
- pub static ENOMSG : c_int = 91;
- pub static EILSEQ : c_int = 92;
- pub static ENOATTR : c_int = 93;
- pub static EBADMSG : c_int = 94;
- pub static EMULTIHOP : c_int = 95;
- pub static ENODATA : c_int = 96;
- pub static ENOLINK : c_int = 97;
- pub static ENOSR : c_int = 98;
- pub static ENOSTR : c_int = 99;
- pub static EPROTO : c_int = 100;
- pub static ETIME : c_int = 101;
- pub static EOPNOTSUPP : c_int = 102;
- pub static ENOPOLICY : c_int = 103;
- pub static ENOTRECOVERABLE : c_int = 104;
- pub static EOWNERDEAD : c_int = 105;
- pub static EQFULL : c_int = 106;
- pub static ELAST : c_int = 106;
- }
- pub mod posix01 {
- use libc::types::os::arch::c95::c_int;
-
- pub static SIGTRAP : c_int = 5;
-
- pub static GLOB_APPEND : c_int = 0x0001;
- pub static GLOB_DOOFFS : c_int = 0x0002;
- pub static GLOB_ERR : c_int = 0x0004;
- pub static GLOB_MARK : c_int = 0x0008;
- pub static GLOB_NOCHECK : c_int = 0x0010;
- pub static GLOB_NOSORT : c_int = 0x0020;
- pub static GLOB_NOESCAPE : c_int = 0x2000;
-
- pub static GLOB_NOSPACE : c_int = -1;
- pub static GLOB_ABORTED : c_int = -2;
- pub static GLOB_NOMATCH : c_int = -3;
-
- pub static POSIX_MADV_NORMAL : c_int = 0;
- pub static POSIX_MADV_RANDOM : c_int = 1;
- pub static POSIX_MADV_SEQUENTIAL : c_int = 2;
- pub static POSIX_MADV_WILLNEED : c_int = 3;
- pub static POSIX_MADV_DONTNEED : c_int = 4;
-
- pub static _SC_IOV_MAX : c_int = 56;
- pub static _SC_GETGR_R_SIZE_MAX : c_int = 70;
- pub static _SC_GETPW_R_SIZE_MAX : c_int = 71;
- pub static _SC_LOGIN_NAME_MAX : c_int = 73;
- pub static _SC_MQ_PRIO_MAX : c_int = 75;
- pub static _SC_THREAD_ATTR_STACKADDR : c_int = 82;
- pub static _SC_THREAD_ATTR_STACKSIZE : c_int = 83;
- pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 85;
- pub static _SC_THREAD_KEYS_MAX : c_int = 86;
- pub static _SC_THREAD_PRIO_INHERIT : c_int = 87;
- pub static _SC_THREAD_PRIO_PROTECT : c_int = 88;
- pub static _SC_THREAD_PRIORITY_SCHEDULING : c_int = 89;
- pub static _SC_THREAD_PROCESS_SHARED : c_int = 90;
- pub static _SC_THREAD_SAFE_FUNCTIONS : c_int = 91;
- pub static _SC_THREAD_STACK_MIN : c_int = 93;
- pub static _SC_THREAD_THREADS_MAX : c_int = 94;
- pub static _SC_THREADS : c_int = 96;
- pub static _SC_TTY_NAME_MAX : c_int = 101;
- pub static _SC_ATEXIT_MAX : c_int = 107;
- pub static _SC_XOPEN_CRYPT : c_int = 108;
- pub static _SC_XOPEN_ENH_I18N : c_int = 109;
- pub static _SC_XOPEN_LEGACY : c_int = 110;
- pub static _SC_XOPEN_REALTIME : c_int = 111;
- pub static _SC_XOPEN_REALTIME_THREADS : c_int = 112;
- pub static _SC_XOPEN_SHM : c_int = 113;
- pub static _SC_XOPEN_UNIX : c_int = 115;
- pub static _SC_XOPEN_VERSION : c_int = 116;
- pub static _SC_XOPEN_XCU_VERSION : c_int = 121;
-
- pub static PTHREAD_CREATE_JOINABLE: c_int = 1;
- pub static PTHREAD_CREATE_DETACHED: c_int = 2;
- }
- pub mod posix08 {
- }
- pub mod bsd44 {
- use libc::types::os::arch::c95::c_int;
-
- pub static MADV_NORMAL : c_int = 0;
- pub static MADV_RANDOM : c_int = 1;
- pub static MADV_SEQUENTIAL : c_int = 2;
- pub static MADV_WILLNEED : c_int = 3;
- pub static MADV_DONTNEED : c_int = 4;
- pub static MADV_FREE : c_int = 5;
- pub static MADV_ZERO_WIRED_PAGES : c_int = 6;
- pub static MADV_FREE_REUSABLE : c_int = 7;
- pub static MADV_FREE_REUSE : c_int = 8;
- pub static MADV_CAN_REUSE : c_int = 9;
-
- pub static MINCORE_INCORE : c_int = 0x1;
- pub static MINCORE_REFERENCED : c_int = 0x2;
- pub static MINCORE_MODIFIED : c_int = 0x4;
- pub static MINCORE_REFERENCED_OTHER : c_int = 0x8;
- pub static MINCORE_MODIFIED_OTHER : c_int = 0x10;
- }
- pub mod extra {
- use libc::types::os::arch::c95::c_int;
-
- pub static O_DSYNC : c_int = 4194304;
- pub static O_SYNC : c_int = 128;
- pub static F_FULLFSYNC : c_int = 51;
-
- pub static MAP_COPY : c_int = 0x0002;
- pub static MAP_RENAME : c_int = 0x0020;
- pub static MAP_NORESERVE : c_int = 0x0040;
- pub static MAP_NOEXTEND : c_int = 0x0100;
- pub static MAP_HASSEMAPHORE : c_int = 0x0200;
- pub static MAP_NOCACHE : c_int = 0x0400;
- pub static MAP_JIT : c_int = 0x0800;
- }
- pub mod sysconf {
- use libc::types::os::arch::c95::c_int;
-
- pub static _SC_ARG_MAX : c_int = 1;
- pub static _SC_CHILD_MAX : c_int = 2;
- pub static _SC_CLK_TCK : c_int = 3;
- pub static _SC_NGROUPS_MAX : c_int = 4;
- pub static _SC_OPEN_MAX : c_int = 5;
- pub static _SC_JOB_CONTROL : c_int = 6;
- pub static _SC_SAVED_IDS : c_int = 7;
- pub static _SC_VERSION : c_int = 8;
- pub static _SC_BC_BASE_MAX : c_int = 9;
- pub static _SC_BC_DIM_MAX : c_int = 10;
- pub static _SC_BC_SCALE_MAX : c_int = 11;
- pub static _SC_BC_STRING_MAX : c_int = 12;
- pub static _SC_COLL_WEIGHTS_MAX : c_int = 13;
- pub static _SC_EXPR_NEST_MAX : c_int = 14;
- pub static _SC_LINE_MAX : c_int = 15;
- pub static _SC_RE_DUP_MAX : c_int = 16;
- pub static _SC_2_VERSION : c_int = 17;
- pub static _SC_2_C_BIND : c_int = 18;
- pub static _SC_2_C_DEV : c_int = 19;
- pub static _SC_2_CHAR_TERM : c_int = 20;
- pub static _SC_2_FORT_DEV : c_int = 21;
- pub static _SC_2_FORT_RUN : c_int = 22;
- pub static _SC_2_LOCALEDEF : c_int = 23;
- pub static _SC_2_SW_DEV : c_int = 24;
- pub static _SC_2_UPE : c_int = 25;
- pub static _SC_STREAM_MAX : c_int = 26;
- pub static _SC_TZNAME_MAX : c_int = 27;
- pub static _SC_ASYNCHRONOUS_IO : c_int = 28;
- pub static _SC_PAGESIZE : c_int = 29;
- pub static _SC_MEMLOCK : c_int = 30;
- pub static _SC_MEMLOCK_RANGE : c_int = 31;
- pub static _SC_MEMORY_PROTECTION : c_int = 32;
- pub static _SC_MESSAGE_PASSING : c_int = 33;
- pub static _SC_PRIORITIZED_IO : c_int = 34;
- pub static _SC_PRIORITY_SCHEDULING : c_int = 35;
- pub static _SC_REALTIME_SIGNALS : c_int = 36;
- pub static _SC_SEMAPHORES : c_int = 37;
- pub static _SC_FSYNC : c_int = 38;
- pub static _SC_SHARED_MEMORY_OBJECTS : c_int = 39;
- pub static _SC_SYNCHRONIZED_IO : c_int = 40;
- pub static _SC_TIMERS : c_int = 41;
- pub static _SC_AIO_LISTIO_MAX : c_int = 42;
- pub static _SC_AIO_MAX : c_int = 43;
- pub static _SC_AIO_PRIO_DELTA_MAX : c_int = 44;
- pub static _SC_DELAYTIMER_MAX : c_int = 45;
- pub static _SC_MQ_OPEN_MAX : c_int = 46;
- pub static _SC_MAPPED_FILES : c_int = 47;
- pub static _SC_RTSIG_MAX : c_int = 48;
- pub static _SC_SEM_NSEMS_MAX : c_int = 49;
- pub static _SC_SEM_VALUE_MAX : c_int = 50;
- pub static _SC_SIGQUEUE_MAX : c_int = 51;
- pub static _SC_TIMER_MAX : c_int = 52;
- pub static _SC_XBS5_ILP32_OFF32 : c_int = 122;
- pub static _SC_XBS5_ILP32_OFFBIG : c_int = 123;
- pub static _SC_XBS5_LP64_OFF64 : c_int = 124;
- pub static _SC_XBS5_LPBIG_OFFBIG : c_int = 125;
- }
- }
-}
-
-
-pub mod funcs {
- // Thankfull most of c95 is universally available and does not vary by OS
- // or anything. The same is not true of POSIX.
-
- pub mod c95 {
- #[nolink]
- pub mod ctype {
- use libc::types::os::arch::c95::{c_char, c_int};
-
- extern {
- pub fn isalnum(c: c_int) -> c_int;
- pub fn isalpha(c: c_int) -> c_int;
- pub fn iscntrl(c: c_int) -> c_int;
- pub fn isdigit(c: c_int) -> c_int;
- pub fn isgraph(c: c_int) -> c_int;
- pub fn islower(c: c_int) -> c_int;
- pub fn isprint(c: c_int) -> c_int;
- pub fn ispunct(c: c_int) -> c_int;
- pub fn isspace(c: c_int) -> c_int;
- pub fn isupper(c: c_int) -> c_int;
- pub fn isxdigit(c: c_int) -> c_int;
- pub fn tolower(c: c_char) -> c_char;
- pub fn toupper(c: c_char) -> c_char;
- }
- }
-
- #[nolink]
- pub mod stdio {
- use libc::types::common::c95::{FILE, c_void, fpos_t};
- use libc::types::os::arch::c95::{c_char, c_int, c_long, size_t};
-
- extern {
- pub fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
- pub fn freopen(filename: *c_char, mode: *c_char, file: *FILE)
- -> *FILE;
- pub fn fflush(file: *FILE) -> c_int;
- pub fn fclose(file: *FILE) -> c_int;
- pub fn remove(filename: *c_char) -> c_int;
- pub fn rename(oldname: *c_char, newname: *c_char) -> c_int;
- pub fn tmpfile() -> *FILE;
- pub fn setvbuf(stream: *FILE,
- buffer: *c_char,
- mode: c_int,
- size: size_t)
- -> c_int;
- pub fn setbuf(stream: *FILE, buf: *c_char);
- // Omitted: printf and scanf variants.
- pub fn fgetc(stream: *FILE) -> c_int;
- pub fn fgets(buf: *mut c_char, n: c_int, stream: *FILE)
- -> *c_char;
- pub fn fputc(c: c_int, stream: *FILE) -> c_int;
- pub fn fputs(s: *c_char, stream: *FILE) -> *c_char;
- // Omitted: getc, getchar (might be macros).
-
- // Omitted: gets, so ridiculously unsafe that it should not
- // survive.
-
- // Omitted: putc, putchar (might be macros).
- pub fn puts(s: *c_char) -> c_int;
- pub fn ungetc(c: c_int, stream: *FILE) -> c_int;
- pub fn fread(ptr: *mut c_void,
- size: size_t,
- nobj: size_t,
- stream: *FILE)
- -> size_t;
- pub fn fwrite(ptr: *c_void,
- size: size_t,
- nobj: size_t,
- stream: *FILE)
- -> size_t;
- pub fn fseek(stream: *FILE, offset: c_long, whence: c_int)
- -> c_int;
- pub fn ftell(stream: *FILE) -> c_long;
- pub fn rewind(stream: *FILE);
- pub fn fgetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
- pub fn fsetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
- pub fn feof(stream: *FILE) -> c_int;
- pub fn ferror(stream: *FILE) -> c_int;
- pub fn perror(s: *c_char);
- }
- }
-
- #[nolink]
- pub mod stdlib {
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::{c_char, c_double, c_int};
- use libc::types::os::arch::c95::{c_long, c_uint, c_ulong};
- use libc::types::os::arch::c95::{size_t};
-
- extern {
- pub fn abs(i: c_int) -> c_int;
- pub fn labs(i: c_long) -> c_long;
- // Omitted: div, ldiv (return pub type incomplete).
- pub fn atof(s: *c_char) -> c_double;
- pub fn atoi(s: *c_char) -> c_int;
- pub fn strtod(s: *c_char, endp: **c_char) -> c_double;
- pub fn strtol(s: *c_char, endp: **c_char, base: c_int)
- -> c_long;
- pub fn strtoul(s: *c_char, endp: **c_char, base: c_int)
- -> c_ulong;
- pub fn calloc(nobj: size_t, size: size_t) -> *c_void;
- pub fn malloc(size: size_t) -> *c_void;
- pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
- pub fn free(p: *c_void);
- pub fn abort() -> !;
- pub fn exit(status: c_int) -> !;
- // Omitted: atexit.
- pub fn system(s: *c_char) -> c_int;
- pub fn getenv(s: *c_char) -> *c_char;
- // Omitted: bsearch, qsort
- pub fn rand() -> c_int;
- pub fn srand(seed: c_uint);
- }
- }
-
- #[nolink]
- pub mod string {
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::{c_char, c_int, size_t};
- use libc::types::os::arch::c95::{wchar_t};
-
- extern {
- pub fn strcpy(dst: *c_char, src: *c_char) -> *c_char;
- pub fn strncpy(dst: *c_char, src: *c_char, n: size_t)
- -> *c_char;
- pub fn strcat(s: *c_char, ct: *c_char) -> *c_char;
- pub fn strncat(s: *c_char, ct: *c_char, n: size_t) -> *c_char;
- pub fn strcmp(cs: *c_char, ct: *c_char) -> c_int;
- pub fn strncmp(cs: *c_char, ct: *c_char, n: size_t) -> c_int;
- pub fn strcoll(cs: *c_char, ct: *c_char) -> c_int;
- pub fn strchr(cs: *c_char, c: c_int) -> *c_char;
- pub fn strrchr(cs: *c_char, c: c_int) -> *c_char;
- pub fn strspn(cs: *c_char, ct: *c_char) -> size_t;
- pub fn strcspn(cs: *c_char, ct: *c_char) -> size_t;
- pub fn strpbrk(cs: *c_char, ct: *c_char) -> *c_char;
- pub fn strstr(cs: *c_char, ct: *c_char) -> *c_char;
- pub fn strlen(cs: *c_char) -> size_t;
- pub fn strerror(n: c_int) -> *c_char;
- pub fn strtok(s: *c_char, t: *c_char) -> *c_char;
- pub fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t;
- pub fn wcslen(buf: *wchar_t) -> size_t;
-
- // Omitted: memcpy, memmove, memset (provided by LLVM)
-
- // These are fine to execute on the Rust stack. They must be,
- // in fact, because LLVM generates calls to them!
- pub fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int;
- pub fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
- }
- }
- }
-
- // Microsoft helpfully underscore-qualifies all of its POSIX-like symbols
- // to make sure you don't use them accidentally. It also randomly deviates
- // from the exact signatures you might otherwise expect, and omits much,
- // so be careful when trying to write portable code; it won't always work
- // with the same POSIX functions and types as other platforms.
-
- #[cfg(target_os = "win32")]
- pub mod posix88 {
- #[nolink]
- pub mod stat_ {
- use libc::types::os::common::posix01::{stat, utimbuf};
- use libc::types::os::arch::c95::{c_int, c_char, wchar_t};
-
- extern {
- #[link_name = "_chmod"]
- pub fn chmod(path: *c_char, mode: c_int) -> c_int;
- #[link_name = "_wchmod"]
- pub fn wchmod(path: *wchar_t, mode: c_int) -> c_int;
- #[link_name = "_mkdir"]
- pub fn mkdir(path: *c_char) -> c_int;
- #[link_name = "_wrmdir"]
- pub fn wrmdir(path: *wchar_t) -> c_int;
- #[link_name = "_fstat64"]
- pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
- #[link_name = "_stat64"]
- pub fn stat(path: *c_char, buf: *mut stat) -> c_int;
- #[link_name = "_wstat64"]
- pub fn wstat(path: *wchar_t, buf: *mut stat) -> c_int;
- #[link_name = "_wutime64"]
- pub fn wutime(file: *wchar_t, buf: *utimbuf) -> c_int;
- }
- }
-
- #[nolink]
- pub mod stdio {
- use libc::types::common::c95::FILE;
- use libc::types::os::arch::c95::{c_int, c_char};
-
- extern {
- #[link_name = "_popen"]
- pub fn popen(command: *c_char, mode: *c_char) -> *FILE;
- #[link_name = "_pclose"]
- pub fn pclose(stream: *FILE) -> c_int;
- #[link_name = "_fdopen"]
- pub fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
- #[link_name = "_fileno"]
- pub fn fileno(stream: *FILE) -> c_int;
- }
- }
-
- #[nolink]
- pub mod fcntl {
- use libc::types::os::arch::c95::{c_int, c_char, wchar_t};
- extern {
- #[link_name = "_open"]
- pub fn open(path: *c_char, oflag: c_int, mode: c_int)
- -> c_int;
- #[link_name = "_wopen"]
- pub fn wopen(path: *wchar_t, oflag: c_int, mode: c_int)
- -> c_int;
- #[link_name = "_creat"]
- pub fn creat(path: *c_char, mode: c_int) -> c_int;
- }
- }
-
- #[nolink]
- pub mod dirent {
- // Not supplied at all.
- }
-
- #[nolink]
- pub mod unistd {
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::{c_int, c_uint, c_char,
- c_long, size_t};
- use libc::types::os::arch::c99::intptr_t;
-
- extern {
- #[link_name = "_access"]
- pub fn access(path: *c_char, amode: c_int) -> c_int;
- #[link_name = "_chdir"]
- pub fn chdir(dir: *c_char) -> c_int;
- #[link_name = "_close"]
- pub fn close(fd: c_int) -> c_int;
- #[link_name = "_dup"]
- pub fn dup(fd: c_int) -> c_int;
- #[link_name = "_dup2"]
- pub fn dup2(src: c_int, dst: c_int) -> c_int;
- #[link_name = "_execv"]
- pub fn execv(prog: *c_char, argv: **c_char) -> intptr_t;
- #[link_name = "_execve"]
- pub fn execve(prog: *c_char, argv: **c_char, envp: **c_char)
- -> c_int;
- #[link_name = "_execvp"]
- pub fn execvp(c: *c_char, argv: **c_char) -> c_int;
- #[link_name = "_execvpe"]
- pub fn execvpe(c: *c_char, argv: **c_char, envp: **c_char)
- -> c_int;
- #[link_name = "_getcwd"]
- pub fn getcwd(buf: *mut c_char, size: size_t) -> *c_char;
- #[link_name = "_getpid"]
- pub fn getpid() -> c_int;
- #[link_name = "_isatty"]
- pub fn isatty(fd: c_int) -> c_int;
- #[link_name = "_lseek"]
- pub fn lseek(fd: c_int, offset: c_long, origin: c_int)
- -> c_long;
- #[link_name = "_pipe"]
- pub fn pipe(fds: *mut c_int, psize: c_uint, textmode: c_int)
- -> c_int;
- #[link_name = "_read"]
- pub fn read(fd: c_int, buf: *mut c_void, count: c_uint)
- -> c_int;
- #[link_name = "_rmdir"]
- pub fn rmdir(path: *c_char) -> c_int;
- #[link_name = "_unlink"]
- pub fn unlink(c: *c_char) -> c_int;
- #[link_name = "_write"]
- pub fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
- }
- }
-
- pub mod mman {
- }
- }
-
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- pub mod posix88 {
- pub mod stat_ {
- use libc::types::os::arch::c95::{c_char, c_int};
- use libc::types::os::arch::posix01::stat;
- use libc::types::os::arch::posix88::mode_t;
-
- #[nolink]
- extern {
- pub fn chmod(path: *c_char, mode: mode_t) -> c_int;
- pub fn fchmod(fd: c_int, mode: mode_t) -> c_int;
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "android")]
- pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
-
- #[cfg(target_os = "macos")]
- #[link_name = "fstat64"]
- pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
-
- pub fn mkdir(path: *c_char, mode: mode_t) -> c_int;
- pub fn mkfifo(path: *c_char, mode: mode_t) -> c_int;
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "android")]
- pub fn stat(path: *c_char, buf: *mut stat) -> c_int;
-
- #[cfg(target_os = "macos")]
- #[link_name = "stat64"]
- pub fn stat(path: *c_char, buf: *mut stat) -> c_int;
- }
- }
-
- #[nolink]
- pub mod stdio {
- use libc::types::common::c95::FILE;
- use libc::types::os::arch::c95::{c_char, c_int};
-
- extern {
- pub fn popen(command: *c_char, mode: *c_char) -> *FILE;
- pub fn pclose(stream: *FILE) -> c_int;
- pub fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
- pub fn fileno(stream: *FILE) -> c_int;
- }
- }
-
- #[nolink]
- pub mod fcntl {
- use libc::types::os::arch::c95::{c_char, c_int};
- use libc::types::os::arch::posix88::mode_t;
-
- extern {
- pub fn open(path: *c_char, oflag: c_int, mode: c_int)
- -> c_int;
- pub fn creat(path: *c_char, mode: mode_t) -> c_int;
- pub fn fcntl(fd: c_int, cmd: c_int) -> c_int;
- }
- }
-
- #[nolink]
- pub mod dirent {
- use libc::types::common::posix88::{DIR, dirent_t};
- use libc::types::os::arch::c95::{c_char, c_int, c_long};
-
- // NB: On OS X opendir and readdir have two versions,
- // one for 32-bit kernelspace and one for 64.
- // We should be linking to the 64-bit ones, called
- // opendir$INODE64, etc. but for some reason rustc
- // doesn't link it correctly on i686, so we're going
- // through a C function that mysteriously does work.
- pub unsafe fn opendir(dirname: *c_char) -> *DIR {
- rust_opendir(dirname)
- }
- pub unsafe fn readdir(dirp: *DIR) -> *dirent_t {
- rust_readdir(dirp)
- }
-
- extern {
- fn rust_opendir(dirname: *c_char) -> *DIR;
- fn rust_readdir(dirp: *DIR) -> *dirent_t;
- }
-
- extern {
- pub fn closedir(dirp: *DIR) -> c_int;
- pub fn rewinddir(dirp: *DIR);
- pub fn seekdir(dirp: *DIR, loc: c_long);
- pub fn telldir(dirp: *DIR) -> c_long;
- }
- }
-
- #[nolink]
- pub mod unistd {
- use libc::types::common::c95::c_void;
- use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint};
- use libc::types::os::arch::c95::{size_t};
- use libc::types::os::arch::posix01::utimbuf;
- use libc::types::os::arch::posix88::{gid_t, off_t, pid_t};
- use libc::types::os::arch::posix88::{ssize_t, uid_t};
-
- pub static _PC_NAME_MAX: c_int = 4;
-
- extern {
- pub fn access(path: *c_char, amode: c_int) -> c_int;
- pub fn alarm(seconds: c_uint) -> c_uint;
- pub fn chdir(dir: *c_char) -> c_int;
- pub fn chown(path: *c_char, uid: uid_t, gid: gid_t) -> c_int;
- pub fn close(fd: c_int) -> c_int;
- pub fn dup(fd: c_int) -> c_int;
- pub fn dup2(src: c_int, dst: c_int) -> c_int;
- pub fn execv(prog: *c_char, argv: **c_char) -> c_int;
- pub fn execve(prog: *c_char, argv: **c_char, envp: **c_char)
- -> c_int;
- pub fn execvp(c: *c_char, argv: **c_char) -> c_int;
- pub fn fork() -> pid_t;
- pub fn fpathconf(filedes: c_int, name: c_int) -> c_long;
- pub fn getcwd(buf: *mut c_char, size: size_t) -> *c_char;
- pub fn getegid() -> gid_t;
- pub fn geteuid() -> uid_t;
- pub fn getgid() -> gid_t ;
- pub fn getgroups(ngroups_max: c_int, groups: *mut gid_t)
- -> c_int;
- pub fn getlogin() -> *c_char;
- pub fn getopt(argc: c_int, argv: **c_char, optstr: *c_char)
- -> c_int;
- pub fn getpgrp() -> pid_t;
- pub fn getpid() -> pid_t;
- pub fn getppid() -> pid_t;
- pub fn getuid() -> uid_t;
- pub fn isatty(fd: c_int) -> c_int;
- pub fn link(src: *c_char, dst: *c_char) -> c_int;
- pub fn lseek(fd: c_int, offset: off_t, whence: c_int)
- -> off_t;
- pub fn pathconf(path: *c_char, name: c_int) -> c_long;
- pub fn pause() -> c_int;
- pub fn pipe(fds: *mut c_int) -> c_int;
- pub fn read(fd: c_int, buf: *mut c_void, count: size_t)
- -> ssize_t;
- pub fn rmdir(path: *c_char) -> c_int;
- pub fn setgid(gid: gid_t) -> c_int;
- pub fn setpgid(pid: pid_t, pgid: pid_t) -> c_int;
- pub fn setsid() -> pid_t;
- pub fn setuid(uid: uid_t) -> c_int;
- pub fn sleep(secs: c_uint) -> c_uint;
- pub fn sysconf(name: c_int) -> c_long;
- pub fn tcgetpgrp(fd: c_int) -> pid_t;
- pub fn ttyname(fd: c_int) -> *c_char;
- pub fn unlink(c: *c_char) -> c_int;
- pub fn write(fd: c_int, buf: *c_void, count: size_t)
- -> ssize_t;
- pub fn pread(fd: c_int, buf: *c_void, count: size_t,
- offset: off_t) -> ssize_t;
- pub fn pwrite(fd: c_int, buf: *c_void, count: size_t,
- offset: off_t) -> ssize_t;
- pub fn utime(file: *c_char, buf: *utimbuf) -> c_int;
- }
- }
-
- #[nolink]
- pub mod signal {
- use libc::types::os::arch::c95::{c_int};
- use libc::types::os::arch::posix88::{pid_t};
-
- extern {
- pub fn kill(pid: pid_t, sig: c_int) -> c_int;
- }
- }
-
- #[nolink]
- pub mod mman {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{size_t, c_int, c_char};
- use libc::types::os::arch::posix88::{mode_t, off_t};
-
- extern {
- pub fn mlock(addr: *c_void, len: size_t) -> c_int;
- pub fn munlock(addr: *c_void, len: size_t) -> c_int;
- pub fn mlockall(flags: c_int) -> c_int;
- pub fn munlockall() -> c_int;
-
- pub fn mmap(addr: *c_void,
- len: size_t,
- prot: c_int,
- flags: c_int,
- fd: c_int,
- offset: off_t)
- -> *mut c_void;
- pub fn munmap(addr: *c_void, len: size_t) -> c_int;
-
- pub fn mprotect(addr: *c_void, len: size_t, prot: c_int)
- -> c_int;
-
- pub fn msync(addr: *c_void, len: size_t, flags: c_int)
- -> c_int;
- pub fn shm_open(name: *c_char, oflag: c_int, mode: mode_t)
- -> c_int;
- pub fn shm_unlink(name: *c_char) -> c_int;
- }
- }
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- pub mod posix01 {
- #[nolink]
- pub mod stat_ {
- use libc::types::os::arch::c95::{c_char, c_int};
- use libc::types::os::arch::posix01::stat;
-
- extern {
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "android")]
- pub fn lstat(path: *c_char, buf: *mut stat) -> c_int;
-
- #[cfg(target_os = "macos")]
- #[link_name = "lstat64"]
- pub fn lstat(path: *c_char, buf: *mut stat) -> c_int;
- }
- }
-
- #[nolink]
- pub mod unistd {
- use libc::types::os::arch::c95::{c_char, c_int, size_t};
- use libc::types::os::arch::posix88::{ssize_t, off_t};
-
- extern {
- pub fn readlink(path: *c_char,
- buf: *mut c_char,
- bufsz: size_t)
- -> ssize_t;
-
- pub fn fsync(fd: c_int) -> c_int;
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- pub fn fdatasync(fd: c_int) -> c_int;
-
- pub fn setenv(name: *c_char, val: *c_char, overwrite: c_int)
- -> c_int;
- pub fn unsetenv(name: *c_char) -> c_int;
- pub fn putenv(string: *c_char) -> c_int;
-
- pub fn symlink(path1: *c_char, path2: *c_char) -> c_int;
-
- pub fn ftruncate(fd: c_int, length: off_t) -> c_int;
- }
- }
-
- #[nolink]
- pub mod wait {
- use libc::types::os::arch::c95::{c_int};
- use libc::types::os::arch::posix88::{pid_t};
-
- extern {
- pub fn waitpid(pid: pid_t, status: *mut c_int, options: c_int)
- -> pid_t;
- }
- }
-
- #[nolink]
- pub mod glob {
- use libc::types::os::arch::c95::{c_char, c_int};
- use libc::types::os::common::posix01::{glob_t};
- use option::Option;
-
- extern {
- pub fn glob(pattern: *c_char,
- flags: c_int,
- errfunc: Option<extern "C" fn(epath: *c_char, errno: int) -> int>,
- pglob: *mut glob_t);
- pub fn globfree(pglob: *mut glob_t);
- }
- }
-
- #[nolink]
- pub mod mman {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{c_int, size_t};
-
- extern {
- pub fn posix_madvise(addr: *c_void,
- len: size_t,
- advice: c_int)
- -> c_int;
- }
- }
- }
-
- #[cfg(target_os = "win32")]
- pub mod posix01 {
- pub mod stat_ {
- }
-
- pub mod unistd {
- }
-
- pub mod glob {
- }
-
- pub mod mman {
- }
- }
-
-
- #[cfg(target_os = "win32")]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- pub mod posix08 {
- pub mod unistd {
- }
- }
-
-
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- pub mod bsd44 {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{c_char, c_uchar, c_int, c_uint,
- size_t};
-
- extern {
- pub fn sysctl(name: *c_int,
- namelen: c_uint,
- oldp: *mut c_void,
- oldlenp: *mut size_t,
- newp: *c_void,
- newlen: size_t)
- -> c_int;
- pub fn sysctlbyname(name: *c_char,
- oldp: *mut c_void,
- oldlenp: *mut size_t,
- newp: *c_void,
- newlen: size_t)
- -> c_int;
- pub fn sysctlnametomib(name: *c_char,
- mibp: *mut c_int,
- sizep: *mut size_t)
- -> c_int;
- pub fn getdtablesize() -> c_int;
- pub fn madvise(addr: *c_void, len: size_t, advice: c_int)
- -> c_int;
- pub fn mincore(addr: *c_void, len: size_t, vec: *c_uchar)
- -> c_int;
- }
- }
-
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- pub mod bsd44 {
- use libc::types::common::c95::{c_void};
- use libc::types::os::arch::c95::{c_uchar, c_int, size_t};
-
- extern {
- pub fn getdtablesize() -> c_int;
- pub fn madvise(addr: *c_void, len: size_t, advice: c_int)
- -> c_int;
- pub fn mincore(addr: *c_void, len: size_t, vec: *c_uchar)
- -> c_int;
- }
- }
-
-
- #[cfg(target_os = "win32")]
- pub mod bsd44 {
- }
-
- #[cfg(target_os = "macos")]
- #[nolink]
- pub mod extra {
- use libc::types::os::arch::c95::{c_char, c_int};
-
- extern {
- pub fn _NSGetExecutablePath(buf: *mut c_char, bufsize: *mut u32)
- -> c_int;
- }
- }
-
- #[cfg(target_os = "freebsd")]
- pub mod extra {
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- pub mod extra {
- }
-
-
- #[cfg(target_os = "win32")]
- pub mod extra {
-
- pub mod kernel32 {
- use libc::types::os::arch::c95::{c_uint};
- use libc::types::os::arch::extra::{BOOL, DWORD, SIZE_T, HMODULE};
- use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPCSTR, LPSTR, LPCH,
- LPDWORD, LPVOID,
- LPCVOID, LPOVERLAPPED};
- use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, LPSTARTUPINFO,
- LPPROCESS_INFORMATION,
- LPMEMORY_BASIC_INFORMATION,
- LPSYSTEM_INFO};
- use libc::types::os::arch::extra::{HANDLE, LPHANDLE, LARGE_INTEGER,
- PLARGE_INTEGER};
-
- extern "system" {
- pub fn GetEnvironmentVariableW(n: LPCWSTR,
- v: LPWSTR,
- nsize: DWORD)
- -> DWORD;
- pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR)
- -> BOOL;
- pub fn GetEnvironmentStringsA() -> LPCH;
- pub fn FreeEnvironmentStringsA(env_ptr: LPCH) -> BOOL;
- pub fn GetModuleFileNameW(hModule: HMODULE,
- lpFilename: LPWSTR,
- nSize: DWORD)
- -> DWORD;
- pub fn CreateDirectoryW(lpPathName: LPCWSTR,
- lpSecurityAttributes:
- LPSECURITY_ATTRIBUTES)
- -> BOOL;
- pub fn CopyFileW(lpExistingFileName: LPCWSTR,
- lpNewFileName: LPCWSTR,
- bFailIfExists: BOOL)
- -> BOOL;
- pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
- pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
- pub fn GetCurrentDirectoryW(nBufferLength: DWORD,
- lpBuffer: LPWSTR)
- -> DWORD;
- pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
- pub fn GetLastError() -> DWORD;
- pub fn FindFirstFileW(fileName: *u16, findFileData: HANDLE)
- -> HANDLE;
- pub fn FindNextFileW(findFile: HANDLE, findFileData: HANDLE)
- -> BOOL;
- pub fn FindClose(findFile: HANDLE) -> BOOL;
- pub fn DuplicateHandle(hSourceProcessHandle: HANDLE,
- hSourceHandle: HANDLE,
- hTargetProcessHandle: HANDLE,
- lpTargetHandle: LPHANDLE,
- dwDesiredAccess: DWORD,
- bInheritHandle: BOOL,
- dwOptions: DWORD)
- -> BOOL;
- pub fn CloseHandle(hObject: HANDLE) -> BOOL;
- pub fn OpenProcess(dwDesiredAccess: DWORD,
- bInheritHandle: BOOL,
- dwProcessId: DWORD)
- -> HANDLE;
- pub fn GetCurrentProcess() -> HANDLE;
- pub fn CreateProcessA(lpApplicationName: LPCSTR,
- lpCommandLine: LPSTR,
- lpProcessAttributes:
- LPSECURITY_ATTRIBUTES,
- lpThreadAttributes:
- LPSECURITY_ATTRIBUTES,
- bInheritHandles: BOOL,
- dwCreationFlags: DWORD,
- lpEnvironment: LPVOID,
- lpCurrentDirectory: LPCSTR,
- lpStartupInfo: LPSTARTUPINFO,
- lpProcessInformation:
- LPPROCESS_INFORMATION)
- -> BOOL;
- pub fn WaitForSingleObject(hHandle: HANDLE,
- dwMilliseconds: DWORD)
- -> DWORD;
- pub fn TerminateProcess(hProcess: HANDLE, uExitCode: c_uint)
- -> BOOL;
- pub fn GetExitCodeProcess(hProcess: HANDLE,
- lpExitCode: LPDWORD)
- -> BOOL;
- pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
- pub fn VirtualAlloc(lpAddress: LPVOID,
- dwSize: SIZE_T,
- flAllocationType: DWORD,
- flProtect: DWORD)
- -> LPVOID;
- pub fn VirtualFree(lpAddress: LPVOID,
- dwSize: SIZE_T,
- dwFreeType: DWORD)
- -> BOOL;
- pub fn VirtualLock(lpAddress: LPVOID, dwSize: SIZE_T) -> BOOL;
- pub fn VirtualUnlock(lpAddress: LPVOID, dwSize: SIZE_T)
- -> BOOL;
- pub fn VirtualProtect(lpAddress: LPVOID,
- dwSize: SIZE_T,
- flNewProtect: DWORD,
- lpflOldProtect: LPDWORD)
- -> BOOL;
- pub fn VirtualQuery(lpAddress: LPCVOID,
- lpBuffer: LPMEMORY_BASIC_INFORMATION,
- dwLength: SIZE_T)
- -> SIZE_T;
- pub fn CreateFileMappingW(hFile: HANDLE,
- lpAttributes: LPSECURITY_ATTRIBUTES,
- flProtect: DWORD,
- dwMaximumSizeHigh: DWORD,
- dwMaximumSizeLow: DWORD,
- lpName: LPCWSTR)
- -> HANDLE;
- pub fn MapViewOfFile(hFileMappingObject: HANDLE,
- dwDesiredAccess: DWORD,
- dwFileOffsetHigh: DWORD,
- dwFileOffsetLow: DWORD,
- dwNumberOfBytesToMap: SIZE_T)
- -> LPVOID;
- pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
- pub fn MoveFileExW(lpExistingFileName: LPCWSTR,
- lpNewFileName: LPCWSTR,
- dwFlags: DWORD) -> BOOL;
- pub fn CreateSymbolicLinkW(lpSymlinkFileName: LPCWSTR,
- lpTargetFileName: LPCWSTR,
- dwFlags: DWORD) -> BOOL;
- pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
- lpTargetFileName: LPCWSTR,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
- -> BOOL;
- pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
- pub fn CreateFileW(lpFileName: LPCWSTR,
- dwDesiredAccess: DWORD,
- dwShareMode: DWORD,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- dwCreationDisposition: DWORD,
- dwFlagsAndAttributes: DWORD,
- hTemplateFile: HANDLE) -> HANDLE;
- pub fn GetFinalPathNameByHandleW(hFile: HANDLE,
- lpszFilePath: LPCWSTR,
- cchFilePath: DWORD,
- dwFlags: DWORD) -> DWORD;
- pub fn ReadFile(hFile: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfBytesToRead: DWORD,
- lpNumberOfBytesRead: LPDWORD,
- lpOverlapped: LPOVERLAPPED) -> BOOL;
- pub fn WriteFile(hFile: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfBytesToRead: DWORD,
- lpNumberOfBytesRead: LPDWORD,
- lpOverlapped: LPOVERLAPPED) -> BOOL;
- pub fn SetFilePointerEx(hFile: HANDLE,
- liDistanceToMove: LARGE_INTEGER,
- lpNewFilePointer: PLARGE_INTEGER,
- dwMoveMethod: DWORD) -> BOOL;
- pub fn SetEndOfFile(hFile: HANDLE) -> BOOL;
- }
- }
-
- pub mod msvcrt {
- use libc::types::os::arch::c95::{c_int, c_long};
-
- #[nolink]
- extern {
- #[link_name = "_commit"]
- pub fn commit(fd: c_int) -> c_int;
-
- #[link_name = "_get_osfhandle"]
- pub fn get_osfhandle(fd: c_int) -> c_long;
- }
- }
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Task local data management
-
-Allows storing arbitrary types inside task-local-storage (TLS), to be accessed
-anywhere within a task, keyed by a global pointer parameterized over the type of
-the TLS slot. Useful for dynamic variables, singletons, and interfacing with
-foreign code with bad callback interfaces.
-
-To declare a new key for storing local data of a particular type, use the
-`local_data_key!` macro. This macro will expand to a `static` item apppriately
-named and annotated. This name is then passed to the functions in this module to
-modify/read the slot specified by the key.
-
-```rust
-use std::local_data;
-
-local_data_key!(key_int: int)
-local_data_key!(key_vector: ~[int])
-
-local_data::set(key_int, 3);
-local_data::get(key_int, |opt| assert_eq!(opt, Some(&3)));
-
-local_data::set(key_vector, ~[4]);
-local_data::get(key_vector, |opt| assert_eq!(opt, Some(&~[4])));
- ```
-
-*/
-
-// Casting 'Arcane Sight' reveals an overwhelming aura of Transmutation
-// magic.
-
-use cast;
-use libc;
-use prelude::*;
-use rt::task::{Task, LocalStorage};
-use util;
-
-/**
- * Indexes a task-local data slot. This pointer is used for comparison to
- * differentiate keys from one another. The actual type `T` is not used anywhere
- * as a member of this type, except that it is parameterized with it to define
- * the type of each key's value.
- *
- * The value of each Key is of the singleton enum KeyValue. These also have the
- * same name as `Key` and their purpose is to take up space in the programs data
- * sections to ensure that each value of the `Key` type points to a unique
- * location.
- */
-pub type Key<T> = &'static KeyValue<T>;
-
-#[allow(missing_doc)]
-pub enum KeyValue<T> { Key }
-
-trait LocalData {}
-impl<T: 'static> LocalData for T {}
-
-// The task-local-map stores all TLS information for the currently running task.
-// It is stored as an owned pointer into the runtime, and it's only allocated
-// when TLS is used for the first time. This map must be very carefully
-// constructed because it has many mutable loans unsoundly handed out on it to
-// the various invocations of TLS requests.
-//
-// One of the most important operations is loaning a value via `get` to a
-// caller. In doing so, the slot that the TLS entry is occupying cannot be
-// invalidated because upon returning its loan state must be updated. Currently
-// the TLS map is a vector, but this is possibly dangerous because the vector
-// can be reallocated/moved when new values are pushed onto it.
-//
-// This problem currently isn't solved in a very elegant way. Inside the `get`
-// function, it internally "invalidates" all references after the loan is
-// finished and looks up into the vector again. In theory this will prevent
-// pointers from being moved under our feet so long as LLVM doesn't go too crazy
-// with the optimizations.
-//
-// n.b. If TLS is used heavily in future, this could be made more efficient with
-// a proper map.
-#[doc(hidden)]
-pub type Map = ~[Option<(*libc::c_void, TLSValue, LoanState)>];
-type TLSValue = ~LocalData;
-
-// Gets the map from the runtime. Lazily initialises if not done so already.
-unsafe fn get_local_map() -> &mut Map {
- use rt::local::Local;
-
- let task: *mut Task = Local::unsafe_borrow();
- match &mut (*task).storage {
- // If the at_exit function is already set, then we just need to take
- // a loan out on the TLS map stored inside
- &LocalStorage(Some(ref mut map_ptr)) => {
- return map_ptr;
- }
- // If this is the first time we've accessed TLS, perform similar
- // actions to the oldsched way of doing things.
- &LocalStorage(ref mut slot) => {
- *slot = Some(~[]);
- match *slot {
- Some(ref mut map_ptr) => { return map_ptr }
- None => abort()
- }
- }
- }
-}
-
-#[deriving(Eq)]
-enum LoanState {
- NoLoan, ImmLoan, MutLoan
-}
-
-impl LoanState {
- fn describe(&self) -> &'static str {
- match *self {
- NoLoan => "no loan",
- ImmLoan => "immutable",
- MutLoan => "mutable"
- }
- }
-}
-
-fn key_to_key_value<T: 'static>(key: Key<T>) -> *libc::c_void {
- unsafe { cast::transmute(key) }
-}
-
-/// Removes a task-local value from task-local storage. This will return
-/// Some(value) if the key was present in TLS, otherwise it will return None.
-///
-/// A runtime assertion will be triggered it removal of TLS value is attempted
-/// while the value is still loaned out via `get` or `get_mut`.
-pub fn pop<T: 'static>(key: Key<T>) -> Option<T> {
- let map = unsafe { get_local_map() };
- let key_value = key_to_key_value(key);
-
- for entry in map.mut_iter() {
- match *entry {
- Some((k, _, loan)) if k == key_value => {
- if loan != NoLoan {
- fail!("TLS value cannot be removed because it is currently \
- borrowed as {}", loan.describe());
- }
- // Move the data out of the `entry` slot via util::replace.
- // This is guaranteed to succeed because we already matched
- // on `Some` above.
- let data = match util::replace(entry, None) {
- Some((_, data, _)) => data,
- None => abort()
- };
-
- // Move `data` into transmute to get out the memory that it
- // owns, we must free it manually later.
- let (_vtable, box): (uint, ~T) = unsafe {
- cast::transmute(data)
- };
-
- // Now that we own `box`, we can just move out of it as we would
- // with any other data.
- return Some(*box);
- }
- _ => {}
- }
- }
- return None;
-}
-
-/// Retrieves a value from TLS. The closure provided is yielded `Some` of a
-/// reference to the value located in TLS if one exists, or `None` if the key
-/// provided is not present in TLS currently.
-///
-/// It is considered a runtime error to attempt to get a value which is already
-/// on loan via the `get_mut` method provided.
-pub fn get<T: 'static, U>(key: Key<T>, f: |Option<&T>| -> U) -> U {
- get_with(key, ImmLoan, f)
-}
-
-/// Retrieves a mutable value from TLS. The closure provided is yielded `Some`
-/// of a reference to the mutable value located in TLS if one exists, or `None`
-/// if the key provided is not present in TLS currently.
-///
-/// It is considered a runtime error to attempt to get a value which is already
-/// on loan via this or the `get` methods. This is similar to how it's a runtime
-/// error to take two mutable loans on an `@mut` box.
-pub fn get_mut<T: 'static, U>(key: Key<T>, f: |Option<&mut T>| -> U) -> U {
- get_with(key, MutLoan, |x| {
- match x {
- None => f(None),
- // We're violating a lot of compiler guarantees with this
- // invocation of `transmute_mut`, but we're doing runtime checks to
- // ensure that it's always valid (only one at a time).
- //
- // there is no need to be upset!
- Some(x) => { f(Some(unsafe { cast::transmute_mut(x) })) }
- }
- })
-}
-
-fn get_with<T:'static,
- U>(
- key: Key<T>,
- state: LoanState,
- f: |Option<&T>| -> U)
- -> U {
- // This function must be extremely careful. Because TLS can store owned
- // values, and we must have some form of `get` function other than `pop`,
- // this function has to give a `&` reference back to the caller.
- //
- // One option is to return the reference, but this cannot be sound because
- // the actual lifetime of the object is not known. The slot in TLS could not
- // be modified until the object goes out of scope, but the TLS code cannot
- // know when this happens.
- //
- // For this reason, the reference is yielded to a specified closure. This
- // way the TLS code knows exactly what the lifetime of the yielded pointer
- // is, allowing callers to acquire references to owned data. This is also
- // sound so long as measures are taken to ensure that while a TLS slot is
- // loaned out to a caller, it's not modified recursively.
- let map = unsafe { get_local_map() };
- let key_value = key_to_key_value(key);
-
- let pos = map.iter().position(|entry| {
- match *entry {
- Some((k, _, _)) if k == key_value => true, _ => false
- }
- });
- match pos {
- None => { return f(None); }
- Some(i) => {
- let ret;
- let mut return_loan = false;
- match map[i] {
- Some((_, ref data, ref mut loan)) => {
- match (state, *loan) {
- (_, NoLoan) => {
- *loan = state;
- return_loan = true;
- }
- (ImmLoan, ImmLoan) => {}
- (want, cur) => {
- fail!("TLS slot cannot be borrowed as {} because \
- it is already borrowed as {}",
- want.describe(), cur.describe());
- }
- }
- // data was created with `~T as ~LocalData`, so we extract
- // pointer part of the trait, (as ~T), and then use
- // compiler coercions to achieve a '&' pointer.
- unsafe {
- match *cast::transmute::<&TLSValue, &(uint, ~T)>(data){
- (_vtable, ref box) => {
- let value: &T = *box;
- ret = f(Some(value));
- }
- }
- }
- }
- _ => abort()
- }
-
- // n.b. 'data' and 'loans' are both invalid pointers at the point
- // 'f' returned because `f` could have appended more TLS items which
- // in turn relocated the vector. Hence we do another lookup here to
- // fixup the loans.
- if return_loan {
- match map[i] {
- Some((_, _, ref mut loan)) => { *loan = NoLoan; }
- None => abort()
- }
- }
- return ret;
- }
- }
-}
-
-fn abort() -> ! {
- unsafe { libc::abort() }
-}
-
-/// Inserts a value into task local storage. If the key is already present in
-/// TLS, then the previous value is removed and replaced with the provided data.
-///
-/// It is considered a runtime error to attempt to set a key which is currently
-/// on loan via the `get` or `get_mut` methods.
-pub fn set<T: 'static>(key: Key<T>, data: T) {
- let map = unsafe { get_local_map() };
- let keyval = key_to_key_value(key);
-
- // When the task-local map is destroyed, all the data needs to be cleaned
- // up. For this reason we can't do some clever tricks to store '~T' as a
- // '*c_void' or something like that. To solve the problem, we cast
- // everything to a trait (LocalData) which is then stored inside the map.
- // Upon destruction of the map, all the objects will be destroyed and the
- // traits have enough information about them to destroy themselves.
- let data = ~data as ~LocalData:;
-
- fn insertion_position(map: &mut Map,
- key: *libc::c_void) -> Option<uint> {
- // First see if the map contains this key already
- let curspot = map.iter().position(|entry| {
- match *entry {
- Some((ekey, _, loan)) if key == ekey => {
- if loan != NoLoan {
- fail!("TLS value cannot be overwritten because it is
- already borrowed as {}", loan.describe())
- }
- true
- }
- _ => false,
- }
- });
- // If it doesn't contain the key, just find a slot that's None
- match curspot {
- Some(i) => Some(i),
- None => map.iter().position(|entry| entry.is_none())
- }
- }
-
- // The type of the local data map must ascribe to Send, so we do the
- // transmute here to add the Send bound back on. This doesn't actually
- // matter because TLS will always own the data (until its moved out) and
- // we're not actually sending it to other schedulers or anything.
- let data: ~LocalData = unsafe { cast::transmute(data) };
- match insertion_position(map, keyval) {
- Some(i) => { map[i] = Some((keyval, data, NoLoan)); }
- None => { map.push(Some((keyval, data, NoLoan))); }
- }
-}
-
-/// Modifies a task-local value by temporarily removing it from task-local
-/// storage and then re-inserting if `Some` is returned from the closure.
-///
-/// This function will have the same runtime errors as generated from `pop` and
-/// `set` (the key must not currently be on loan
-pub fn modify<T: 'static>(key: Key<T>, f: |Option<T>| -> Option<T>) {
- match f(pop(key)) {
- Some(next) => { set(key, next); }
- None => {}
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use super::*;
- use task;
-
- #[test]
- fn test_tls_multitask() {
- static my_key: Key<@~str> = &Key;
- set(my_key, @~"parent data");
- do task::spawn {
- // TLS shouldn't carry over.
- assert!(get(my_key, |k| k.map(|k| *k)).is_none());
- set(my_key, @~"child data");
- assert!(*(get(my_key, |k| k.map(|k| *k)).unwrap()) ==
- ~"child data");
- // should be cleaned up for us
- }
- // Must work multiple times
- assert!(*(get(my_key, |k| k.map(|k| *k)).unwrap()) == ~"parent data");
- assert!(*(get(my_key, |k| k.map(|k| *k)).unwrap()) == ~"parent data");
- assert!(*(get(my_key, |k| k.map(|k| *k)).unwrap()) == ~"parent data");
- }
-
- #[test]
- fn test_tls_overwrite() {
- static my_key: Key<@~str> = &Key;
- set(my_key, @~"first data");
- set(my_key, @~"next data"); // Shouldn't leak.
- assert!(*(get(my_key, |k| k.map(|k| *k)).unwrap()) == ~"next data");
- }
-
- #[test]
- fn test_tls_pop() {
- static my_key: Key<@~str> = &Key;
- set(my_key, @~"weasel");
- assert!(*(pop(my_key).unwrap()) == ~"weasel");
- // Pop must remove the data from the map.
- assert!(pop(my_key).is_none());
- }
-
- #[test]
- fn test_tls_modify() {
- static my_key: Key<@~str> = &Key;
- modify(my_key, |data| {
- match data {
- Some(@ref val) => fail!("unwelcome value: {}", *val),
- None => Some(@~"first data")
- }
- });
- modify(my_key, |data| {
- match data {
- Some(@~"first data") => Some(@~"next data"),
- Some(@ref val) => fail!("wrong value: {}", *val),
- None => fail!("missing value")
- }
- });
- assert!(*(pop(my_key).unwrap()) == ~"next data");
- }
-
- #[test]
- fn test_tls_crust_automorestack_memorial_bug() {
- // This might result in a stack-canary clobber if the runtime fails to
- // set sp_limit to 0 when calling the cleanup extern - it might
- // automatically jump over to the rust stack, which causes next_c_sp
- // to get recorded as something within a rust stack segment. Then a
- // subsequent upcall (esp. for logging, think vsnprintf) would run on
- // a stack smaller than 1 MB.
- static my_key: Key<@~str> = &Key;
- do task::spawn {
- set(my_key, @~"hax");
- }
- }
-
- #[test]
- fn test_tls_multiple_types() {
- static str_key: Key<@~str> = &Key;
- static box_key: Key<@@()> = &Key;
- static int_key: Key<@int> = &Key;
- do task::spawn {
- set(str_key, @~"string data");
- set(box_key, @@());
- set(int_key, @42);
- }
- }
-
- #[test]
- fn test_tls_overwrite_multiple_types() {
- static str_key: Key<@~str> = &Key;
- static box_key: Key<@@()> = &Key;
- static int_key: Key<@int> = &Key;
- do task::spawn {
- set(str_key, @~"string data");
- set(int_key, @42);
- // This could cause a segfault if overwriting-destruction is done
- // with the crazy polymorphic transmute rather than the provided
- // finaliser.
- set(int_key, @31337);
- }
- }
-
- #[test]
- #[should_fail]
- fn test_tls_cleanup_on_failure() {
- static str_key: Key<@~str> = &Key;
- static box_key: Key<@@()> = &Key;
- static int_key: Key<@int> = &Key;
- set(str_key, @~"parent data");
- set(box_key, @@());
- do task::spawn {
- // spawn_linked
- set(str_key, @~"string data");
- set(box_key, @@());
- set(int_key, @42);
- fail!();
- }
- // Not quite nondeterministic.
- set(int_key, @31337);
- fail!();
- }
-
- #[test]
- fn test_static_pointer() {
- static key: Key<@&'static int> = &Key;
- static VALUE: int = 0;
- let v: @&'static int = @&VALUE;
- set(key, v);
- }
-
- #[test]
- fn test_owned() {
- static key: Key<~int> = &Key;
- set(key, ~1);
-
- get(key, |v| {
- get(key, |v| {
- get(key, |v| {
- assert_eq!(**v.unwrap(), 1);
- });
- assert_eq!(**v.unwrap(), 1);
- });
- assert_eq!(**v.unwrap(), 1);
- });
- set(key, ~2);
- get(key, |v| {
- assert_eq!(**v.unwrap(), 2);
- })
- }
-
- #[test]
- fn test_get_mut() {
- static key: Key<int> = &Key;
- set(key, 1);
-
- get_mut(key, |v| {
- *v.unwrap() = 2;
- });
-
- get(key, |v| {
- assert_eq!(*v.unwrap(), 2);
- })
- }
-
- #[test]
- fn test_same_key_type() {
- static key1: Key<int> = &Key;
- static key2: Key<int> = &Key;
- static key3: Key<int> = &Key;
- static key4: Key<int> = &Key;
- static key5: Key<int> = &Key;
- set(key1, 1);
- set(key2, 2);
- set(key3, 3);
- set(key4, 4);
- set(key5, 5);
-
- get(key1, |x| assert_eq!(*x.unwrap(), 1));
- get(key2, |x| assert_eq!(*x.unwrap(), 2));
- get(key3, |x| assert_eq!(*x.unwrap(), 3));
- get(key4, |x| assert_eq!(*x.unwrap(), 4));
- get(key5, |x| assert_eq!(*x.unwrap(), 5));
- }
-
- #[test]
- #[should_fail]
- fn test_nested_get_set1() {
- static key: Key<int> = &Key;
- set(key, 4);
- get(key, |_| {
- set(key, 4);
- })
- }
-
- #[test]
- #[should_fail]
- fn test_nested_get_mut2() {
- static key: Key<int> = &Key;
- set(key, 4);
- get(key, |_| {
- get_mut(key, |_| {})
- })
- }
-
- #[test]
- #[should_fail]
- fn test_nested_get_mut3() {
- static key: Key<int> = &Key;
- set(key, 4);
- get_mut(key, |_| {
- get(key, |_| {})
- })
- }
-
- #[test]
- #[should_fail]
- fn test_nested_get_mut4() {
- static key: Key<int> = &Key;
- set(key, 4);
- get_mut(key, |_| {
- get_mut(key, |_| {})
- })
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Logging
-
-This module is used by the compiler when emitting output for the logging family
-of macros. The methods of this module shouldn't necessarily be used directly,
-but rather through the logging macros defined.
-
-There are five macros that the logging subsystem uses:
-
-* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
- related `format!` arguments
-* `debug!(...)` - a macro hard-wired to the log level of 4
-* `info!(...)` - a macro hard-wired to the log level of 3
-* `warn!(...)` - a macro hard-wired to the log level of 2
-* `error!(...)` - a macro hard-wired to the log level of 1
-
-All of these macros use the same style of syntax as the `format!` syntax
-extension. Details about the syntax can be found in the documentation of
-`std::fmt` along with the Rust tutorial/manual
-
-## Enabling logging
-
-Log levels are controlled on a per-module basis, and by default all logging is
-disabled except for `error!` (a log level of 1). Logging is controlled via the
-`RUST_LOG` environment variable. The value of this environment variable is a
-comma-separated list of logging directives. A logging directive is of the form:
-
-```
-path::to::module=log_level
-```
-
-The path to the module is rooted in the name of the crate it was compiled for,
-so if your program is contained in a file `hello.rs`, for example, to turn on
-logging for this file you would use a value of `RUST_LOG=hello`. Furthermore,
-this path is a prefix-search, so all modules nested in the specified module will
-also have logging enabled.
-
-The actual `log_level` is optional to specify. If omitted, all logging will be
-enabled. If specified, the it must be either a numeric in the range of 1-255, or
-it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
-is specified, then all logging less than or equal to that numeral is enabled.
-For example, if logging level 3 is active, error, warn, and info logs will be
-printed, but debug will be omitted.
-
-As the log level for a module is optional, the module to enable logging for is
-also optional. If only a `log_level` is provided, then the global log level for
-all modules is set to this value.
-
-Some examples of valid values of `RUST_LOG` are:
-
-```
-hello // turns on all logging for the 'hello' module
-info // turns on all info logging
-hello=debug // turns on debug logging for 'hello'
-hello=3 // turns on info logging for 'hello'
-hello,std::hashmap // turns on hello, and std's hashmap logging
-error,hello=warn // turn on global error logging and also warn for hello
-```
-
-## Performance and Side Effects
-
-Each of these macros will expand to code similar to:
-
-```rust
-if log_level <= my_module_log_level() {
- ::std::logging::log(log_level, format!(...));
-}
-```
-
-What this means is that each of these macros are very cheap at runtime if
-they're turned off (just a load and an integer comparison). This also means that
-if logging is disabled, none of the components of the log will be executed.
-
-## Useful Values
-
-For convenience, if a value of `::help` is set for `RUST_LOG`, a program will
-start, print out all modules registered for logging, and then exit.
-
-*/
-
-use fmt;
-use option::*;
-use rt::local::Local;
-use rt::logging::{Logger, StdErrLogger};
-use rt::task::Task;
-
-/// This function is called directly by the compiler when using the logging
-/// macros. This function does not take into account whether the log level
-/// specified is active or not, it will always log something if this method is
-/// called.
-///
-/// It is not recommended to call this function directly, rather it should be
-/// invoked through the logging family of macros.
-pub fn log(_level: u32, args: &fmt::Arguments) {
- unsafe {
- let optional_task: Option<*mut Task> = Local::try_unsafe_borrow();
- match optional_task {
- Some(local) => {
- match (*local).logger {
- // Use the available logger if we have one
- Some(ref mut logger) => return logger.log(args),
- None => {
- let mut logger = StdErrLogger::new();
- logger.log(args);
- (*local).logger = Some(logger);
- }
- }
- }
- None => {}
- }
- // There is no logger anywhere, just write to stderr
- let mut logger = StdErrLogger::new();
- logger.log(args);
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations on managed box types
-
-use ptr::to_unsafe_ptr;
-
-#[cfg(not(test))] use cmp::*;
-
-pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
-pub static RC_IMMORTAL : uint = 0x77777777;
-
-/// Returns the refcount of a shared box (as just before calling this)
-#[inline]
-pub fn refcount<T>(t: @T) -> uint {
- use unstable::raw::Repr;
- unsafe { (*t.repr()).ref_count - 1 }
-}
-
-/// Determine if two shared boxes point to the same object
-#[inline]
-pub fn ptr_eq<T>(a: @T, b: @T) -> bool {
- let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
- a_ptr == b_ptr
-}
-
-/// Determine if two mutable shared boxes point to the same object
-#[inline]
-pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
- let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
- a_ptr == b_ptr
-}
-
-#[cfg(not(test))]
-impl<T:Eq> Eq for @T {
- #[inline]
- fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
- #[inline]
- fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
-}
-
-#[cfg(not(test))]
-impl<T:Eq> Eq for @mut T {
- #[inline]
- fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) }
- #[inline]
- fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) }
-}
-
-#[cfg(not(test))]
-impl<T:Ord> Ord for @T {
- #[inline]
- fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
- #[inline]
- fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
- #[inline]
- fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
- #[inline]
- fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
-}
-
-#[cfg(not(test))]
-impl<T:Ord> Ord for @mut T {
- #[inline]
- fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) }
- #[inline]
- fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) }
- #[inline]
- fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) }
- #[inline]
- fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) }
-}
-
-#[cfg(not(test))]
-impl<T: TotalOrd> TotalOrd for @T {
- #[inline]
- fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
-}
-
-#[cfg(not(test))]
-impl<T: TotalOrd> TotalOrd for @mut T {
- #[inline]
- fn cmp(&self, other: &@mut T) -> Ordering { (**self).cmp(*other) }
-}
-
-#[cfg(not(test))]
-impl<T: TotalEq> TotalEq for @T {
- #[inline]
- fn equals(&self, other: &@T) -> bool { (**self).equals(*other) }
-}
-
-#[cfg(not(test))]
-impl<T: TotalEq> TotalEq for @mut T {
- #[inline]
- fn equals(&self, other: &@mut T) -> bool { (**self).equals(*other) }
-}
-#[test]
-fn test() {
- let x = @3;
- let y = @3;
- assert!((ptr_eq::<int>(x, x)));
- assert!((ptr_eq::<int>(y, y)));
- assert!((!ptr_eq::<int>(x, y)));
- assert!((!ptr_eq::<int>(y, x)));
-}
-
-#[test]
-fn refcount_test() {
- use clone::Clone;
-
- let x = @3;
- assert_eq!(refcount(x), 1);
- let y = x.clone();
- assert_eq!(refcount(x), 2);
- assert_eq!(refcount(y), 2);
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Functions relating to memory layout
-
-use unstable::intrinsics;
-
-/// Returns the size of a type
-#[inline]
-pub fn size_of<T>() -> uint {
- unsafe { intrinsics::size_of::<T>() }
-}
-
-/// Returns the size of the type that `_val` points to
-#[inline]
-pub fn size_of_val<T>(_val: &T) -> uint {
- size_of::<T>()
-}
-
-/// Returns the size of a type, or 1 if the actual size is zero.
-///
-/// Useful for building structures containing variable-length arrays.
-#[inline]
-pub fn nonzero_size_of<T>() -> uint {
- let s = size_of::<T>();
- if s == 0 { 1 } else { s }
-}
-
-/// Returns the size of the type of the value that `_val` points to
-#[inline]
-pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
- nonzero_size_of::<T>()
-}
-
-/// Returns the ABI-required minimum alignment of a type
-///
-/// This is the alignment used for struct fields. It may be smaller
-/// than the preferred alignment.
-#[inline]
-pub fn min_align_of<T>() -> uint {
- unsafe { intrinsics::min_align_of::<T>() }
-}
-
-/// Returns the ABI-required minimum alignment of the type of the value that
-/// `_val` points to
-#[inline]
-pub fn min_align_of_val<T>(_val: &T) -> uint {
- min_align_of::<T>()
-}
-
-/// Returns the preferred alignment of a type
-#[inline]
-pub fn pref_align_of<T>() -> uint {
- unsafe { intrinsics::pref_align_of::<T>() }
-}
-
-/// Returns the preferred alignment of the type of the value that
-/// `_val` points to
-#[inline]
-pub fn pref_align_of_val<T>(_val: &T) -> uint {
- pref_align_of::<T>()
-}
-
-#[cfg(test)]
-mod tests {
- use mem::*;
-
- #[test]
- fn size_of_basic() {
- assert_eq!(size_of::<u8>(), 1u);
- assert_eq!(size_of::<u16>(), 2u);
- assert_eq!(size_of::<u32>(), 4u);
- assert_eq!(size_of::<u64>(), 8u);
- }
-
- #[test]
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "arm")]
- #[cfg(target_arch = "mips")]
- fn size_of_32() {
- assert_eq!(size_of::<uint>(), 4u);
- assert_eq!(size_of::<*uint>(), 4u);
- }
-
- #[test]
- #[cfg(target_arch = "x86_64")]
- fn size_of_64() {
- assert_eq!(size_of::<uint>(), 8u);
- assert_eq!(size_of::<*uint>(), 8u);
- }
-
- #[test]
- fn size_of_val_basic() {
- assert_eq!(size_of_val(&1u8), 1);
- assert_eq!(size_of_val(&1u16), 2);
- assert_eq!(size_of_val(&1u32), 4);
- assert_eq!(size_of_val(&1u64), 8);
- }
-
- #[test]
- fn nonzero_size_of_basic() {
- type Z = [i8, ..0];
- assert_eq!(size_of::<Z>(), 0u);
- assert_eq!(nonzero_size_of::<Z>(), 1u);
- assert_eq!(nonzero_size_of::<uint>(), size_of::<uint>());
- }
-
- #[test]
- fn nonzero_size_of_val_basic() {
- let z = [0u8, ..0];
- assert_eq!(size_of_val(&z), 0u);
- assert_eq!(nonzero_size_of_val(&z), 1u);
- assert_eq!(nonzero_size_of_val(&1u), size_of_val(&1u));
- }
-
- #[test]
- fn align_of_basic() {
- assert_eq!(pref_align_of::<u8>(), 1u);
- assert_eq!(pref_align_of::<u16>(), 2u);
- assert_eq!(pref_align_of::<u32>(), 4u);
- }
-
- #[test]
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "arm")]
- #[cfg(target_arch = "mips")]
- fn align_of_32() {
- assert_eq!(pref_align_of::<uint>(), 4u);
- assert_eq!(pref_align_of::<*uint>(), 4u);
- }
-
- #[test]
- #[cfg(target_arch = "x86_64")]
- fn align_of_64() {
- assert_eq!(pref_align_of::<uint>(), 8u);
- assert_eq!(pref_align_of::<*uint>(), 8u);
- }
-
- #[test]
- fn align_of_val_basic() {
- assert_eq!(pref_align_of_val(&1u8), 1u);
- assert_eq!(pref_align_of_val(&1u16), 2u);
- assert_eq!(pref_align_of_val(&1u32), 4u);
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[allow(missing_doc)];
-#[allow(non_uppercase_statics)];
-
-// function names are almost identical to C's libmath, a few have been
-// renamed, grep for "rename:"
-
-pub mod c_double_utils {
- use libc::{c_double, c_int};
-
- #[link_name = "m"]
- extern {
- // Alpabetically sorted by link_name
-
- pub fn acos(n: c_double) -> c_double;
- pub fn asin(n: c_double) -> c_double;
- pub fn atan(n: c_double) -> c_double;
- pub fn atan2(a: c_double, b: c_double) -> c_double;
- pub fn cbrt(n: c_double) -> c_double;
- pub fn ceil(n: c_double) -> c_double;
- pub fn copysign(x: c_double, y: c_double) -> c_double;
- pub fn cos(n: c_double) -> c_double;
- pub fn cosh(n: c_double) -> c_double;
- pub fn erf(n: c_double) -> c_double;
- pub fn erfc(n: c_double) -> c_double;
- pub fn exp(n: c_double) -> c_double;
- // rename: for consistency with underscore usage elsewhere
- #[link_name="expm1"]
- pub fn exp_m1(n: c_double) -> c_double;
- pub fn exp2(n: c_double) -> c_double;
- #[link_name="fabs"]
- pub fn abs(n: c_double) -> c_double;
- // rename: for clarity and consistency with add/sub/mul/div
- #[link_name="fdim"]
- pub fn abs_sub(a: c_double, b: c_double) -> c_double;
- pub fn floor(n: c_double) -> c_double;
- // rename: for clarity and consistency with add/sub/mul/div
- #[link_name="fma"]
- pub fn mul_add(a: c_double, b: c_double, c: c_double) -> c_double;
- #[link_name="fmax"]
- pub fn fmax(a: c_double, b: c_double) -> c_double;
- #[link_name="fmin"]
- pub fn fmin(a: c_double, b: c_double) -> c_double;
- #[link_name="nextafter"]
- pub fn next_after(x: c_double, y: c_double) -> c_double;
- pub fn frexp(n: c_double, value: &mut c_int) -> c_double;
- pub fn hypot(x: c_double, y: c_double) -> c_double;
- pub fn ldexp(x: c_double, n: c_int) -> c_double;
- #[cfg(unix)]
- #[link_name="lgamma_r"]
- pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double;
- #[cfg(windows)]
- #[link_name="__lgamma_r"]
- pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double;
- // renamed: ln seems more natural
- #[link_name="log"]
- pub fn ln(n: c_double) -> c_double;
- // renamed: "logb" /often/ is confused for log2 by beginners
- #[link_name="logb"]
- pub fn log_radix(n: c_double) -> c_double;
- // renamed: to be consitent with log as ln
- #[link_name="log1p"]
- pub fn ln_1p(n: c_double) -> c_double;
- pub fn log10(n: c_double) -> c_double;
- pub fn log2(n: c_double) -> c_double;
- #[link_name="ilogb"]
- pub fn ilog_radix(n: c_double) -> c_int;
- pub fn modf(n: c_double, iptr: &mut c_double) -> c_double;
- pub fn pow(n: c_double, e: c_double) -> c_double;
- // FIXME (#1379): enable when rounding modes become available
- // fn rint(n: c_double) -> c_double;
- pub fn round(n: c_double) -> c_double;
- // rename: for consistency with logradix
- #[link_name="scalbn"]
- pub fn ldexp_radix(n: c_double, i: c_int) -> c_double;
- pub fn sin(n: c_double) -> c_double;
- pub fn sinh(n: c_double) -> c_double;
- pub fn sqrt(n: c_double) -> c_double;
- pub fn tan(n: c_double) -> c_double;
- pub fn tanh(n: c_double) -> c_double;
- pub fn tgamma(n: c_double) -> c_double;
- pub fn trunc(n: c_double) -> c_double;
-
- // These are commonly only available for doubles
-
- pub fn j0(n: c_double) -> c_double;
- pub fn j1(n: c_double) -> c_double;
- pub fn jn(i: c_int, n: c_double) -> c_double;
-
- pub fn y0(n: c_double) -> c_double;
- pub fn y1(n: c_double) -> c_double;
- pub fn yn(i: c_int, n: c_double) -> c_double;
- }
-}
-
-pub mod c_float_utils {
- use libc::{c_float, c_int};
-
- #[link_name = "m"]
- extern {
- // Alpabetically sorted by link_name
-
- #[link_name="acosf"]
- pub fn acos(n: c_float) -> c_float;
- #[link_name="asinf"]
- pub fn asin(n: c_float) -> c_float;
- #[link_name="atanf"]
- pub fn atan(n: c_float) -> c_float;
- #[link_name="atan2f"]
- pub fn atan2(a: c_float, b: c_float) -> c_float;
- #[link_name="cbrtf"]
- pub fn cbrt(n: c_float) -> c_float;
- #[link_name="ceilf"]
- pub fn ceil(n: c_float) -> c_float;
- #[link_name="copysignf"]
- pub fn copysign(x: c_float, y: c_float) -> c_float;
- #[link_name="cosf"]
- pub fn cos(n: c_float) -> c_float;
- #[link_name="coshf"]
- pub fn cosh(n: c_float) -> c_float;
- #[link_name="erff"]
- pub fn erf(n: c_float) -> c_float;
- #[link_name="erfcf"]
- pub fn erfc(n: c_float) -> c_float;
- #[link_name="expf"]
- pub fn exp(n: c_float) -> c_float;
- #[link_name="expm1f"]
- pub fn exp_m1(n: c_float) -> c_float;
- #[link_name="exp2f"]
- pub fn exp2(n: c_float) -> c_float;
- #[link_name="fabsf"]
- pub fn abs(n: c_float) -> c_float;
- #[link_name="fdimf"]
- pub fn abs_sub(a: c_float, b: c_float) -> c_float;
- #[link_name="floorf"]
- pub fn floor(n: c_float) -> c_float;
- #[link_name="frexpf"]
- pub fn frexp(n: c_float, value: &mut c_int) -> c_float;
- #[link_name="fmaf"]
- pub fn mul_add(a: c_float, b: c_float, c: c_float) -> c_float;
- #[link_name="fmaxf"]
- pub fn fmax(a: c_float, b: c_float) -> c_float;
- #[link_name="fminf"]
- pub fn fmin(a: c_float, b: c_float) -> c_float;
- #[link_name="nextafterf"]
- pub fn next_after(x: c_float, y: c_float) -> c_float;
- #[link_name="hypotf"]
- pub fn hypot(x: c_float, y: c_float) -> c_float;
- #[link_name="ldexpf"]
- pub fn ldexp(x: c_float, n: c_int) -> c_float;
-
- #[cfg(unix)]
- #[link_name="lgammaf_r"]
- pub fn lgamma(n: c_float, sign: &mut c_int) -> c_float;
-
- #[cfg(windows)]
- #[link_name="__lgammaf_r"]
- pub fn lgamma(n: c_float, sign: &mut c_int) -> c_float;
-
- #[link_name="logf"]
- pub fn ln(n: c_float) -> c_float;
- #[link_name="logbf"]
- pub fn log_radix(n: c_float) -> c_float;
- #[link_name="log1pf"]
- pub fn ln_1p(n: c_float) -> c_float;
- #[link_name="log2f"]
- pub fn log2(n: c_float) -> c_float;
- #[link_name="log10f"]
- pub fn log10(n: c_float) -> c_float;
- #[link_name="ilogbf"]
- pub fn ilog_radix(n: c_float) -> c_int;
- #[link_name="modff"]
- pub fn modf(n: c_float, iptr: &mut c_float) -> c_float;
- #[link_name="powf"]
- pub fn pow(n: c_float, e: c_float) -> c_float;
- // FIXME (#1379): enable when rounding modes become available
- // #[link_name="rintf"] fn rint(n: c_float) -> c_float;
- #[link_name="roundf"]
- pub fn round(n: c_float) -> c_float;
- #[link_name="scalbnf"]
- pub fn ldexp_radix(n: c_float, i: c_int) -> c_float;
- #[link_name="sinf"]
- pub fn sin(n: c_float) -> c_float;
- #[link_name="sinhf"]
- pub fn sinh(n: c_float) -> c_float;
- #[link_name="sqrtf"]
- pub fn sqrt(n: c_float) -> c_float;
- #[link_name="tanf"]
- pub fn tan(n: c_float) -> c_float;
- #[link_name="tanhf"]
- pub fn tanh(n: c_float) -> c_float;
- #[link_name="tgammaf"]
- pub fn tgamma(n: c_float) -> c_float;
- #[link_name="truncf"]
- pub fn trunc(n: c_float) -> c_float;
- }
-}
-
-// PORT check these by running src/etc/machconsts.c for your architecture
-
-// FIXME obtain machine float/math constants automatically (Issue #1986)
-
-pub mod c_float_targ_consts {
- pub static radix: uint = 2u;
- pub static mantissa_digits: uint = 24u;
- pub static digits: uint = 6u;
- pub static min_exp: uint = -125u;
- pub static max_exp: uint = 128u;
- pub static min_10_exp: int = -37;
- pub static max_10_exp: int = 38;
- // FIXME (#1433): this is wrong, replace with hexadecimal (%a) staticants
- // below.
- pub static min_value: f32 = 1.175494e-38_f32;
- pub static max_value: f32 = 3.402823e+38_f32;
- pub static epsilon: f32 = 0.000000_f32;
-}
-
-pub mod c_double_targ_consts {
- pub static radix: uint = 2u;
- pub static mantissa_digits: uint = 53u;
- pub static digits: uint = 15u;
- pub static min_exp: uint = -1021u;
- pub static max_exp: uint = 1024u;
- pub static min_10_exp: int = -307;
- pub static max_10_exp: int = 308;
- // FIXME (#1433): this is wrong, replace with hexadecimal (%a) staticants
- // below.
- pub static min_value: f64 = 2.225074e-308_f64;
- pub static max_value: f64 = 1.797693e+308_f64;
- pub static epsilon: f64 = 2.220446e-16_f64;
-}
-
-/*
-
-FIXME use these once they can be parsed (see Issue #1433)
-
-pub mod c_float_math_consts {
- pub static pi: c_float = 0x1.921fb6p+1_f32;
- pub static div_1_pi: c_float = 0x1.45f306p-2_f32;
- pub static div_2_pi: c_float = 0x1.45f306p-1_f32;
- pub static div_pi_2: c_float = 0x1.921fb6p+0_f32;
- pub static div_pi_4: c_float = 0x1.921fb6p-1_f32;
- pub static div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32;
- pub static e: c_float = 0x1.5bf0a8p+1_f32;
- pub static log2_e: c_float = 0x1.715476p+0_f32;
- pub static log10_e: c_float = 0x1.bcb7b2p-2_f32;
- pub static ln_2: c_float = 0x1.62e43p-1_f32;
- pub static ln_10: c_float = 0x1.26bb1cp+1_f32;
- pub static sqrt2: c_float = 0x1.6a09e6p+0_f32;
- pub static div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32;
-}
-
-pub mod c_double_math_consts {
- pub static pi: c_double = 0x1.921fb54442d18p+1_f64;
- pub static div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64;
- pub static div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64;
- pub static div_pi_2: c_double = 0x1.921fb54442d18p+0_f64;
- pub static div_pi_4: c_double = 0x1.921fb54442d18p-1_f64;
- pub static div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64;
- pub static e: c_double = 0x1.5bf0a8b145769p+1_f64;
- pub static log2_e: c_double = 0x1.71547652b82fep+0_f64;
- pub static log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64;
- pub static ln_2: c_double = 0x1.62e42fefa39efp-1_f64;
- pub static ln_10: c_double = 0x1.26bb1bbb55516p+1_f64;
- pub static sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64;
- pub static div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64;
-}
-
-pub mod c_float_targ_consts {
- pub static radix: uint = 2u;
- pub static mantissa_digits: uint = 24u;
- pub static digits: uint = 6u;
- pub static min_exp: int = -125;
- pub static max_exp: int = 128;
- pub static min_10_exp: int = -37;
- pub static max_10_exp: int = 38;
- pub static min_value: c_float = 0x1p-126_f32;
- pub static max_value: c_float = 0x1.fffffep+127_f32;
- pub static epsilon: c_float = 0x1p-23_f32;
-}
-
-pub mod c_double_targ_consts {
- pub static radix: uint = 2u;
- pub static mantissa_digits: uint = 53u;
- pub static digits: uint = 15u;
- pub static min_exp: int = -1021;
- pub static max_exp: int = 1024;
- pub static min_10_exp: int = -307;
- pub static max_10_exp: int = 308;
- pub static min_value: c_double = 0x1p-1022_f64;
- pub static max_value: c_double = 0x1.fffffffffffffp+1023_f64;
- pub static epsilon: c_double = 0x1p-52_f64;
-}
-
-*/
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `f32`
-#[allow(missing_doc)];
-
-use default::Default;
-use libc::c_int;
-use num::{Zero, One, strconv};
-use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
-use num;
-use prelude::*;
-use to_str;
-
-pub use cmath::c_float_targ_consts::*;
-
-use self::delegated::*;
-
-macro_rules! delegate(
- (
- $(
- fn $name:ident(
- $(
- $arg:ident : $arg_ty:ty
- ),*
- ) -> $rv:ty = $bound_name:path
- ),*
- ) => (
- // An inner module is required to get the #[inline] attribute on the
- // functions.
- mod delegated {
- use cmath::c_float_utils;
- use libc::{c_float, c_int};
- use unstable::intrinsics;
-
- $(
- #[inline]
- pub fn $name($( $arg : $arg_ty ),*) -> $rv {
- unsafe {
- $bound_name($( $arg ),*)
- }
- }
- )*
- }
- )
-)
-
-delegate!(
- // intrinsics
- fn abs(n: f32) -> f32 = intrinsics::fabsf32,
- fn cos(n: f32) -> f32 = intrinsics::cosf32,
- fn exp(n: f32) -> f32 = intrinsics::expf32,
- fn exp2(n: f32) -> f32 = intrinsics::exp2f32,
- fn floor(x: f32) -> f32 = intrinsics::floorf32,
- fn ln(n: f32) -> f32 = intrinsics::logf32,
- fn log10(n: f32) -> f32 = intrinsics::log10f32,
- fn log2(n: f32) -> f32 = intrinsics::log2f32,
- fn mul_add(a: f32, b: f32, c: f32) -> f32 = intrinsics::fmaf32,
- fn pow(n: f32, e: f32) -> f32 = intrinsics::powf32,
- fn powi(n: f32, e: c_int) -> f32 = intrinsics::powif32,
- fn sin(n: f32) -> f32 = intrinsics::sinf32,
- fn sqrt(n: f32) -> f32 = intrinsics::sqrtf32,
-
- // LLVM 3.3 required to use intrinsics for these four
- fn ceil(n: c_float) -> c_float = c_float_utils::ceil,
- fn trunc(n: c_float) -> c_float = c_float_utils::trunc,
- /*
- fn ceil(n: f32) -> f32 = intrinsics::ceilf32,
- fn trunc(n: f32) -> f32 = intrinsics::truncf32,
- fn rint(n: f32) -> f32 = intrinsics::rintf32,
- fn nearbyint(n: f32) -> f32 = intrinsics::nearbyintf32,
- */
-
- // cmath
- fn acos(n: c_float) -> c_float = c_float_utils::acos,
- fn asin(n: c_float) -> c_float = c_float_utils::asin,
- fn atan(n: c_float) -> c_float = c_float_utils::atan,
- fn atan2(a: c_float, b: c_float) -> c_float = c_float_utils::atan2,
- fn cbrt(n: c_float) -> c_float = c_float_utils::cbrt,
- fn copysign(x: c_float, y: c_float) -> c_float = c_float_utils::copysign,
- fn cosh(n: c_float) -> c_float = c_float_utils::cosh,
- fn erf(n: c_float) -> c_float = c_float_utils::erf,
- fn erfc(n: c_float) -> c_float = c_float_utils::erfc,
- fn exp_m1(n: c_float) -> c_float = c_float_utils::exp_m1,
- fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub,
- fn next_after(x: c_float, y: c_float) -> c_float = c_float_utils::next_after,
- fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp,
- fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot,
- fn ldexp(x: c_float, n: c_int) -> c_float = c_float_utils::ldexp,
- fn lgamma(n: c_float, sign: &mut c_int) -> c_float = c_float_utils::lgamma,
- fn log_radix(n: c_float) -> c_float = c_float_utils::log_radix,
- fn ln_1p(n: c_float) -> c_float = c_float_utils::ln_1p,
- fn ilog_radix(n: c_float) -> c_int = c_float_utils::ilog_radix,
- fn modf(n: c_float, iptr: &mut c_float) -> c_float = c_float_utils::modf,
- fn round(n: c_float) -> c_float = c_float_utils::round,
- fn ldexp_radix(n: c_float, i: c_int) -> c_float = c_float_utils::ldexp_radix,
- fn sinh(n: c_float) -> c_float = c_float_utils::sinh,
- fn tan(n: c_float) -> c_float = c_float_utils::tan,
- fn tanh(n: c_float) -> c_float = c_float_utils::tanh,
- fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma
-)
-
-// These are not defined inside consts:: for consistency with
-// the integer types
-
-pub static NAN: f32 = 0.0_f32/0.0_f32;
-
-pub static INFINITY: f32 = 1.0_f32/0.0_f32;
-
-pub static NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
-
-// FIXME (#1999): replace the predicates below with llvm intrinsics or
-// calls to the libmath macros in the rust runtime for performance.
-
-// FIXME (#1999): add is_normal, is_subnormal, and fpclassify.
-
-/* Module: consts */
-pub mod consts {
- // FIXME (requires Issue #1433 to fix): replace with mathematical
- // staticants from cmath.
- /// Archimedes' constant
- pub static PI: f32 = 3.14159265358979323846264338327950288_f32;
-
- /// pi/2.0
- pub static FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
-
- /// pi/4.0
- pub static FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
-
- /// 1.0/pi
- pub static FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
-
- /// 2.0/pi
- pub static FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
-
- /// 2.0/sqrt(pi)
- pub static FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32;
-
- /// sqrt(2.0)
- pub static SQRT2: f32 = 1.41421356237309504880168872420969808_f32;
-
- /// 1.0/sqrt(2.0)
- pub static FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32;
-
- /// Euler's number
- pub static E: f32 = 2.71828182845904523536028747135266250_f32;
-
- /// log2(e)
- pub static LOG2_E: f32 = 1.44269504088896340735992468100189214_f32;
-
- /// log10(e)
- pub static LOG10_E: f32 = 0.434294481903251827651128918916605082_f32;
-
- /// ln(2.0)
- pub static LN_2: f32 = 0.693147180559945309417232121458176568_f32;
-
- /// ln(10.0)
- pub static LN_10: f32 = 2.30258509299404568401799145468436421_f32;
-}
-
-impl Num for f32 {}
-
-#[cfg(not(test))]
-impl Eq for f32 {
- #[inline]
- fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
-}
-
-#[cfg(not(test))]
-impl ApproxEq<f32> for f32 {
- #[inline]
- fn approx_epsilon() -> f32 { 1.0e-6 }
-
- #[inline]
- fn approx_eq(&self, other: &f32) -> bool {
- self.approx_eq_eps(other, &1.0e-6)
- }
-
- #[inline]
- fn approx_eq_eps(&self, other: &f32, approx_epsilon: &f32) -> bool {
- (*self - *other).abs() < *approx_epsilon
- }
-}
-
-#[cfg(not(test))]
-impl Ord for f32 {
- #[inline]
- fn lt(&self, other: &f32) -> bool { (*self) < (*other) }
- #[inline]
- fn le(&self, other: &f32) -> bool { (*self) <= (*other) }
- #[inline]
- fn ge(&self, other: &f32) -> bool { (*self) >= (*other) }
- #[inline]
- fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
-}
-
-impl Orderable for f32 {
- /// Returns `NAN` if either of the numbers are `NAN`.
- #[inline]
- fn min(&self, other: &f32) -> f32 {
- match () {
- _ if self.is_nan() => *self,
- _ if other.is_nan() => *other,
- _ if *self < *other => *self,
- _ => *other,
- }
- }
-
- /// Returns `NAN` if either of the numbers are `NAN`.
- #[inline]
- fn max(&self, other: &f32) -> f32 {
- match () {
- _ if self.is_nan() => *self,
- _ if other.is_nan() => *other,
- _ if *self > *other => *self,
- _ => *other,
- }
- }
-
- /// Returns the number constrained within the range `mn <= self <= mx`.
- /// If any of the numbers are `NAN` then `NAN` is returned.
- #[inline]
- fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
- match () {
- _ if self.is_nan() => *self,
- _ if !(*self <= *mx) => *mx,
- _ if !(*self >= *mn) => *mn,
- _ => *self,
- }
- }
-}
-
-impl Default for f32 {
- #[inline]
- fn default() -> f32 { 0.0 }
-}
-
-impl Zero for f32 {
- #[inline]
- fn zero() -> f32 { 0.0 }
-
- /// Returns true if the number is equal to either `0.0` or `-0.0`
- #[inline]
- fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
-}
-
-impl One for f32 {
- #[inline]
- fn one() -> f32 { 1.0 }
-}
-
-#[cfg(not(test))]
-impl Add<f32,f32> for f32 {
- #[inline]
- fn add(&self, other: &f32) -> f32 { *self + *other }
-}
-
-#[cfg(not(test))]
-impl Sub<f32,f32> for f32 {
- #[inline]
- fn sub(&self, other: &f32) -> f32 { *self - *other }
-}
-
-#[cfg(not(test))]
-impl Mul<f32,f32> for f32 {
- #[inline]
- fn mul(&self, other: &f32) -> f32 { *self * *other }
-}
-
-#[cfg(not(test))]
-impl Div<f32,f32> for f32 {
- #[inline]
- fn div(&self, other: &f32) -> f32 { *self / *other }
-}
-
-#[cfg(not(test))]
-impl Rem<f32,f32> for f32 {
- #[inline]
- fn rem(&self, other: &f32) -> f32 { *self % *other }
-}
-
-#[cfg(not(test))]
-impl Neg<f32> for f32 {
- #[inline]
- fn neg(&self) -> f32 { -*self }
-}
-
-impl Signed for f32 {
- /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
- #[inline]
- fn abs(&self) -> f32 { abs(*self) }
-
- ///
- /// The positive difference of two numbers. Returns `0.0` if the number is less than or
- /// equal to `other`, otherwise the difference between`self` and `other` is returned.
- ///
- #[inline]
- fn abs_sub(&self, other: &f32) -> f32 { abs_sub(*self, *other) }
-
- ///
- /// # Returns
- ///
- /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
- /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
- /// - `NAN` if the number is NaN
- ///
- #[inline]
- fn signum(&self) -> f32 {
- if self.is_nan() { NAN } else { copysign(1.0, *self) }
- }
-
- /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
- #[inline]
- fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY }
-
- /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
- #[inline]
- fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
-}
-
-impl Round for f32 {
- /// Round half-way cases toward `NEG_INFINITY`
- #[inline]
- fn floor(&self) -> f32 { floor(*self) }
-
- /// Round half-way cases toward `INFINITY`
- #[inline]
- fn ceil(&self) -> f32 { ceil(*self) }
-
- /// Round half-way cases away from `0.0`
- #[inline]
- fn round(&self) -> f32 { round(*self) }
-
- /// The integer part of the number (rounds towards `0.0`)
- #[inline]
- fn trunc(&self) -> f32 { trunc(*self) }
-
- ///
- /// The fractional part of the number, satisfying:
- ///
- /// ```rust
- /// assert!(x == trunc(x) + fract(x))
- /// ```
- ///
- #[inline]
- fn fract(&self) -> f32 { *self - self.trunc() }
-}
-
-impl Fractional for f32 {
- /// The reciprocal (multiplicative inverse) of the number
- #[inline]
- fn recip(&self) -> f32 { 1.0 / *self }
-}
-
-impl Algebraic for f32 {
- #[inline]
- fn pow(&self, n: &f32) -> f32 { pow(*self, *n) }
-
- #[inline]
- fn sqrt(&self) -> f32 { sqrt(*self) }
-
- #[inline]
- fn rsqrt(&self) -> f32 { self.sqrt().recip() }
-
- #[inline]
- fn cbrt(&self) -> f32 { cbrt(*self) }
-
- #[inline]
- fn hypot(&self, other: &f32) -> f32 { hypot(*self, *other) }
-}
-
-impl Trigonometric for f32 {
- #[inline]
- fn sin(&self) -> f32 { sin(*self) }
-
- #[inline]
- fn cos(&self) -> f32 { cos(*self) }
-
- #[inline]
- fn tan(&self) -> f32 { tan(*self) }
-
- #[inline]
- fn asin(&self) -> f32 { asin(*self) }
-
- #[inline]
- fn acos(&self) -> f32 { acos(*self) }
-
- #[inline]
- fn atan(&self) -> f32 { atan(*self) }
-
- #[inline]
- fn atan2(&self, other: &f32) -> f32 { atan2(*self, *other) }
-
- /// Simultaneously computes the sine and cosine of the number
- #[inline]
- fn sin_cos(&self) -> (f32, f32) {
- (self.sin(), self.cos())
- }
-}
-
-impl Exponential for f32 {
- /// Returns the exponential of the number
- #[inline]
- fn exp(&self) -> f32 { exp(*self) }
-
- /// Returns 2 raised to the power of the number
- #[inline]
- fn exp2(&self) -> f32 { exp2(*self) }
-
- /// Returns the natural logarithm of the number
- #[inline]
- fn ln(&self) -> f32 { ln(*self) }
-
- /// Returns the logarithm of the number with respect to an arbitrary base
- #[inline]
- fn log(&self, base: &f32) -> f32 { self.ln() / base.ln() }
-
- /// Returns the base 2 logarithm of the number
- #[inline]
- fn log2(&self) -> f32 { log2(*self) }
-
- /// Returns the base 10 logarithm of the number
- #[inline]
- fn log10(&self) -> f32 { log10(*self) }
-}
-
-impl Hyperbolic for f32 {
- #[inline]
- fn sinh(&self) -> f32 { sinh(*self) }
-
- #[inline]
- fn cosh(&self) -> f32 { cosh(*self) }
-
- #[inline]
- fn tanh(&self) -> f32 { tanh(*self) }
-
- ///
- /// Inverse hyperbolic sine
- ///
- /// # Returns
- ///
- /// - on success, the inverse hyperbolic sine of `self` will be returned
- /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
- /// - `NAN` if `self` is `NAN`
- ///
- #[inline]
- fn asinh(&self) -> f32 {
- match *self {
- NEG_INFINITY => NEG_INFINITY,
- x => (x + ((x * x) + 1.0).sqrt()).ln(),
- }
- }
-
- ///
- /// Inverse hyperbolic cosine
- ///
- /// # Returns
- ///
- /// - on success, the inverse hyperbolic cosine of `self` will be returned
- /// - `INFINITY` if `self` is `INFINITY`
- /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
- ///
- #[inline]
- fn acosh(&self) -> f32 {
- match *self {
- x if x < 1.0 => Float::nan(),
- x => (x + ((x * x) - 1.0).sqrt()).ln(),
- }
- }
-
- ///
- /// Inverse hyperbolic tangent
- ///
- /// # Returns
- ///
- /// - on success, the inverse hyperbolic tangent of `self` will be returned
- /// - `self` if `self` is `0.0` or `-0.0`
- /// - `INFINITY` if `self` is `1.0`
- /// - `NEG_INFINITY` if `self` is `-1.0`
- /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
- /// (including `INFINITY` and `NEG_INFINITY`)
- ///
- #[inline]
- fn atanh(&self) -> f32 {
- 0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
- }
-}
-
-impl Real for f32 {
- /// Archimedes' constant
- #[inline]
- fn pi() -> f32 { 3.14159265358979323846264338327950288 }
-
- /// 2.0 * pi
- #[inline]
- fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
-
- /// pi / 2.0
- #[inline]
- fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
-
- /// pi / 3.0
- #[inline]
- fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
-
- /// pi / 4.0
- #[inline]
- fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
-
- /// pi / 6.0
- #[inline]
- fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
-
- /// pi / 8.0
- #[inline]
- fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
-
- /// 1 .0/ pi
- #[inline]
- fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
-
- /// 2.0 / pi
- #[inline]
- fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
-
- /// 2.0 / sqrt(pi)
- #[inline]
- fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
-
- /// sqrt(2.0)
- #[inline]
- fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
-
- /// 1.0 / sqrt(2.0)
- #[inline]
- fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
-
- /// Euler's number
- #[inline]
- fn e() -> f32 { 2.71828182845904523536028747135266250 }
-
- /// log2(e)
- #[inline]
- fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
-
- /// log10(e)
- #[inline]
- fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
-
- /// ln(2.0)
- #[inline]
- fn ln_2() -> f32 { 0.693147180559945309417232121458176568 }
-
- /// ln(10.0)
- #[inline]
- fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
-
- /// Converts to degrees, assuming the number is in radians
- #[inline]
- fn to_degrees(&self) -> f32 { *self * (180.0f32 / Real::pi()) }
-
- /// Converts to radians, assuming the number is in degrees
- #[inline]
- fn to_radians(&self) -> f32 {
- let value: f32 = Real::pi();
- *self * (value / 180.0f32)
- }
-}
-
-impl Bounded for f32 {
- #[inline]
- fn min_value() -> f32 { 1.17549435e-38 }
-
- #[inline]
- fn max_value() -> f32 { 3.40282347e+38 }
-}
-
-impl Primitive for f32 {
- #[inline]
- fn bits(_: Option<f32>) -> uint { 32 }
-
- #[inline]
- fn bytes(_: Option<f32>) -> uint { Primitive::bits(Some(0f32)) / 8 }
-
- #[inline]
- fn is_signed(_: Option<f32>) -> bool { true }
-}
-
-impl Float for f32 {
- #[inline]
- fn nan() -> f32 { 0.0 / 0.0 }
-
- #[inline]
- fn infinity() -> f32 { 1.0 / 0.0 }
-
- #[inline]
- fn neg_infinity() -> f32 { -1.0 / 0.0 }
-
- #[inline]
- fn neg_zero() -> f32 { -0.0 }
-
- /// Returns `true` if the number is NaN
- #[inline]
- fn is_nan(&self) -> bool { *self != *self }
-
- /// Returns `true` if the number is infinite
- #[inline]
- fn is_infinite(&self) -> bool {
- *self == Float::infinity() || *self == Float::neg_infinity()
- }
-
- /// Returns `true` if the number is neither infinite or NaN
- #[inline]
- fn is_finite(&self) -> bool {
- !(self.is_nan() || self.is_infinite())
- }
-
- /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
- #[inline]
- fn is_normal(&self) -> bool {
- self.classify() == FPNormal
- }
-
- /// Returns the floating point category of the number. If only one property is going to
- /// be tested, it is generally faster to use the specific predicate instead.
- fn classify(&self) -> FPCategory {
- static EXP_MASK: u32 = 0x7f800000;
- static MAN_MASK: u32 = 0x007fffff;
-
- match (
- unsafe { ::cast::transmute::<f32,u32>(*self) } & MAN_MASK,
- unsafe { ::cast::transmute::<f32,u32>(*self) } & EXP_MASK,
- ) {
- (0, 0) => FPZero,
- (_, 0) => FPSubnormal,
- (0, EXP_MASK) => FPInfinite,
- (_, EXP_MASK) => FPNaN,
- _ => FPNormal,
- }
- }
-
- #[inline]
- fn mantissa_digits(_: Option<f32>) -> uint { 24 }
-
- #[inline]
- fn digits(_: Option<f32>) -> uint { 6 }
-
- #[inline]
- fn epsilon() -> f32 { 1.19209290e-07 }
-
- #[inline]
- fn min_exp(_: Option<f32>) -> int { -125 }
-
- #[inline]
- fn max_exp(_: Option<f32>) -> int { 128 }
-
- #[inline]
- fn min_10_exp(_: Option<f32>) -> int { -37 }
-
- #[inline]
- fn max_10_exp(_: Option<f32>) -> int { 38 }
-
- /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
- #[inline]
- fn ldexp(x: f32, exp: int) -> f32 {
- ldexp(x, exp as c_int)
- }
-
- ///
- /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
- ///
- /// - `self = x * pow(2, exp)`
- /// - `0.5 <= abs(x) < 1.0`
- ///
- #[inline]
- fn frexp(&self) -> (f32, int) {
- let mut exp = 0;
- let x = frexp(*self, &mut exp);
- (x, exp as int)
- }
-
- ///
- /// Returns the exponential of the number, minus `1`, in a way that is accurate
- /// even if the number is close to zero
- ///
- #[inline]
- fn exp_m1(&self) -> f32 { exp_m1(*self) }
-
- ///
- /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
- /// than if the operations were performed separately
- ///
- #[inline]
- fn ln_1p(&self) -> f32 { ln_1p(*self) }
-
- ///
- /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
- /// produces a more accurate result with better performance than a separate multiplication
- /// operation followed by an add.
- ///
- #[inline]
- fn mul_add(&self, a: f32, b: f32) -> f32 {
- mul_add(*self, a, b)
- }
-
- /// Returns the next representable floating-point value in the direction of `other`
- #[inline]
- fn next_after(&self, other: f32) -> f32 {
- next_after(*self, other)
- }
-}
-
-//
-// Section: String Conversions
-//
-
-///
-/// Converts a float to a string
-///
-/// # Arguments
-///
-/// * num - The float value
-///
-#[inline]
-pub fn to_str(num: f32) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 10u, true, strconv::SignNeg, strconv::DigAll);
- r
-}
-
-///
-/// Converts a float to a string in hexadecimal format
-///
-/// # Arguments
-///
-/// * num - The float value
-///
-#[inline]
-pub fn to_str_hex(num: f32) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 16u, true, strconv::SignNeg, strconv::DigAll);
- r
-}
-
-///
-/// Converts a float to a string in a given radix, and a flag indicating
-/// whether it's a special value
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * radix - The base to use
-///
-#[inline]
-pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
- strconv::float_to_str_common(num, rdx, true,
- strconv::SignNeg, strconv::DigAll)
-}
-
-///
-/// Converts a float to a string with exactly the number of
-/// provided significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-///
-#[inline]
-pub fn to_str_exact(num: f32, dig: uint) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
- r
-}
-
-///
-/// Converts a float to a string with a maximum number of
-/// significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-///
-#[inline]
-pub fn to_str_digits(num: f32, dig: uint) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
- r
-}
-
-impl to_str::ToStr for f32 {
- #[inline]
- fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
-}
-
-impl num::ToStrRadix for f32 {
- /// Converts a float to a string in a given radix
- ///
- /// # Arguments
- ///
- /// * num - The float value
- /// * radix - The base to use
- ///
- /// # Failure
- ///
- /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
- /// possible misinterpretation of the result at higher bases. If those values
- /// are expected, use `to_str_radix_special()` instead.
- #[inline]
- fn to_str_radix(&self, rdx: uint) -> ~str {
- let (r, special) = strconv::float_to_str_common(
- *self, rdx, true, strconv::SignNeg, strconv::DigAll);
- if special { fail!("number has a special value, \
- try to_str_radix_special() if those are expected") }
- r
- }
-}
-
-///
-/// Convert a string in base 16 to a float.
-/// Accepts a optional binary exponent.
-///
-/// This function accepts strings such as
-///
-/// * 'a4.fe'
-/// * '+a4.fe', equivalent to 'a4.fe'
-/// * '-a4.fe'
-/// * '2b.aP128', or equivalently, '2b.ap128'
-/// * '2b.aP-128'
-/// * '.' (understood as 0)
-/// * 'c.'
-/// * '.c', or, equivalently, '0.c'
-/// * '+inf', 'inf', '-inf', 'NaN'
-///
-/// Leading and trailing whitespace represent an error.
-///
-/// # Arguments
-///
-/// * num - A string
-///
-/// # Return value
-///
-/// `None` if the string did not represent a valid number. Otherwise,
-/// `Some(n)` where `n` is the floating-point number represented by `[num]`.
-///
-#[inline]
-pub fn from_str_hex(num: &str) -> Option<f32> {
- strconv::from_str_common(num, 16u, true, true, true,
- strconv::ExpBin, false, false)
-}
-
-impl FromStr for f32 {
- ///
- /// Convert a string in base 10 to a float.
- /// Accepts a optional decimal exponent.
- ///
- /// This function accepts strings such as
- ///
- /// * '3.14'
- /// * '+3.14', equivalent to '3.14'
- /// * '-3.14'
- /// * '2.5E10', or equivalently, '2.5e10'
- /// * '2.5E-10'
- /// * '.' (understood as 0)
- /// * '5.'
- /// * '.5', or, equivalently, '0.5'
- /// * '+inf', 'inf', '-inf', 'NaN'
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * num - A string
- ///
- /// # Return value
- ///
- /// `None` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `num`.
- ///
- #[inline]
- fn from_str(val: &str) -> Option<f32> {
- strconv::from_str_common(val, 10u, true, true, true,
- strconv::ExpDec, false, false)
- }
-}
-
-impl num::FromStrRadix for f32 {
- ///
- /// Convert a string in an given base to a float.
- ///
- /// Due to possible conflicts, this function does **not** accept
- /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
- /// does it recognize exponents of any kind.
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * num - A string
- /// * radix - The base to use. Must lie in the range [2 .. 36]
- ///
- /// # Return value
- ///
- /// `None` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `num`.
- ///
- #[inline]
- fn from_str_radix(val: &str, rdx: uint) -> Option<f32> {
- strconv::from_str_common(val, rdx, true, true, false,
- strconv::ExpNone, false, false)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use f32::*;
- use prelude::*;
-
- use num::*;
- use num;
- use mem;
-
- #[test]
- fn test_num() {
- num::test_num(10f32, 2f32);
- }
-
- #[test]
- fn test_min() {
- assert_eq!(1f32.min(&2f32), 1f32);
- assert_eq!(2f32.min(&1f32), 1f32);
- }
-
- #[test]
- fn test_max() {
- assert_eq!(1f32.max(&2f32), 2f32);
- assert_eq!(2f32.max(&1f32), 2f32);
- }
-
- #[test]
- fn test_clamp() {
- assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
- assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
- assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
-
- let nan: f32 = Float::nan();
- assert!(3f32.clamp(&nan, &4f32).is_nan());
- assert!(3f32.clamp(&2f32, &nan).is_nan());
- assert!(nan.clamp(&2f32, &4f32).is_nan());
- }
-
- #[test]
- fn test_floor() {
- assert_approx_eq!(1.0f32.floor(), 1.0f32);
- assert_approx_eq!(1.3f32.floor(), 1.0f32);
- assert_approx_eq!(1.5f32.floor(), 1.0f32);
- assert_approx_eq!(1.7f32.floor(), 1.0f32);
- assert_approx_eq!(0.0f32.floor(), 0.0f32);
- assert_approx_eq!((-0.0f32).floor(), -0.0f32);
- assert_approx_eq!((-1.0f32).floor(), -1.0f32);
- assert_approx_eq!((-1.3f32).floor(), -2.0f32);
- assert_approx_eq!((-1.5f32).floor(), -2.0f32);
- assert_approx_eq!((-1.7f32).floor(), -2.0f32);
- }
-
- #[test]
- fn test_ceil() {
- assert_approx_eq!(1.0f32.ceil(), 1.0f32);
- assert_approx_eq!(1.3f32.ceil(), 2.0f32);
- assert_approx_eq!(1.5f32.ceil(), 2.0f32);
- assert_approx_eq!(1.7f32.ceil(), 2.0f32);
- assert_approx_eq!(0.0f32.ceil(), 0.0f32);
- assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
- assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
- assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
- assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
- assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
- }
-
- #[test]
- fn test_round() {
- assert_approx_eq!(1.0f32.round(), 1.0f32);
- assert_approx_eq!(1.3f32.round(), 1.0f32);
- assert_approx_eq!(1.5f32.round(), 2.0f32);
- assert_approx_eq!(1.7f32.round(), 2.0f32);
- assert_approx_eq!(0.0f32.round(), 0.0f32);
- assert_approx_eq!((-0.0f32).round(), -0.0f32);
- assert_approx_eq!((-1.0f32).round(), -1.0f32);
- assert_approx_eq!((-1.3f32).round(), -1.0f32);
- assert_approx_eq!((-1.5f32).round(), -2.0f32);
- assert_approx_eq!((-1.7f32).round(), -2.0f32);
- }
-
- #[test]
- fn test_trunc() {
- assert_approx_eq!(1.0f32.trunc(), 1.0f32);
- assert_approx_eq!(1.3f32.trunc(), 1.0f32);
- assert_approx_eq!(1.5f32.trunc(), 1.0f32);
- assert_approx_eq!(1.7f32.trunc(), 1.0f32);
- assert_approx_eq!(0.0f32.trunc(), 0.0f32);
- assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
- assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
- assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
- assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
- assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
- }
-
- #[test]
- fn test_fract() {
- assert_approx_eq!(1.0f32.fract(), 0.0f32);
- assert_approx_eq!(1.3f32.fract(), 0.3f32);
- assert_approx_eq!(1.5f32.fract(), 0.5f32);
- assert_approx_eq!(1.7f32.fract(), 0.7f32);
- assert_approx_eq!(0.0f32.fract(), 0.0f32);
- assert_approx_eq!((-0.0f32).fract(), -0.0f32);
- assert_approx_eq!((-1.0f32).fract(), -0.0f32);
- assert_approx_eq!((-1.3f32).fract(), -0.3f32);
- assert_approx_eq!((-1.5f32).fract(), -0.5f32);
- assert_approx_eq!((-1.7f32).fract(), -0.7f32);
- }
-
- #[test]
- fn test_asinh() {
- assert_eq!(0.0f32.asinh(), 0.0f32);
- assert_eq!((-0.0f32).asinh(), -0.0f32);
-
- let inf: f32 = Float::infinity();
- let neg_inf: f32 = Float::neg_infinity();
- let nan: f32 = Float::nan();
- assert_eq!(inf.asinh(), inf);
- assert_eq!(neg_inf.asinh(), neg_inf);
- assert!(nan.asinh().is_nan());
- assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
- assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
- }
-
- #[test]
- fn test_acosh() {
- assert_eq!(1.0f32.acosh(), 0.0f32);
- assert!(0.999f32.acosh().is_nan());
-
- let inf: f32 = Float::infinity();
- let neg_inf: f32 = Float::neg_infinity();
- let nan: f32 = Float::nan();
- assert_eq!(inf.acosh(), inf);
- assert!(neg_inf.acosh().is_nan());
- assert!(nan.acosh().is_nan());
- assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
- assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
- }
-
- #[test]
- fn test_atanh() {
- assert_eq!(0.0f32.atanh(), 0.0f32);
- assert_eq!((-0.0f32).atanh(), -0.0f32);
-
- let inf32: f32 = Float::infinity();
- let neg_inf32: f32 = Float::neg_infinity();
- assert_eq!(1.0f32.atanh(), inf32);
- assert_eq!((-1.0f32).atanh(), neg_inf32);
-
- assert!(2f64.atanh().atanh().is_nan());
- assert!((-2f64).atanh().atanh().is_nan());
-
- let inf64: f32 = Float::infinity();
- let neg_inf64: f32 = Float::neg_infinity();
- let nan32: f32 = Float::nan();
- assert!(inf64.atanh().is_nan());
- assert!(neg_inf64.atanh().is_nan());
- assert!(nan32.atanh().is_nan());
-
- assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
- assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
- }
-
- #[test]
- fn test_real_consts() {
- let pi: f32 = Real::pi();
- let two_pi: f32 = Real::two_pi();
- let frac_pi_2: f32 = Real::frac_pi_2();
- let frac_pi_3: f32 = Real::frac_pi_3();
- let frac_pi_4: f32 = Real::frac_pi_4();
- let frac_pi_6: f32 = Real::frac_pi_6();
- let frac_pi_8: f32 = Real::frac_pi_8();
- let frac_1_pi: f32 = Real::frac_1_pi();
- let frac_2_pi: f32 = Real::frac_2_pi();
- let frac_2_sqrtpi: f32 = Real::frac_2_sqrtpi();
- let sqrt2: f32 = Real::sqrt2();
- let frac_1_sqrt2: f32 = Real::frac_1_sqrt2();
- let e: f32 = Real::e();
- let log2_e: f32 = Real::log2_e();
- let log10_e: f32 = Real::log10_e();
- let ln_2: f32 = Real::ln_2();
- let ln_10: f32 = Real::ln_10();
-
- assert_approx_eq!(two_pi, 2f32 * pi);
- assert_approx_eq!(frac_pi_2, pi / 2f32);
- assert_approx_eq!(frac_pi_3, pi / 3f32);
- assert_approx_eq!(frac_pi_4, pi / 4f32);
- assert_approx_eq!(frac_pi_6, pi / 6f32);
- assert_approx_eq!(frac_pi_8, pi / 8f32);
- assert_approx_eq!(frac_1_pi, 1f32 / pi);
- assert_approx_eq!(frac_2_pi, 2f32 / pi);
- assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
- assert_approx_eq!(sqrt2, 2f32.sqrt());
- assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
- assert_approx_eq!(log2_e, e.log2());
- assert_approx_eq!(log10_e, e.log10());
- assert_approx_eq!(ln_2, 2f32.ln());
- assert_approx_eq!(ln_10, 10f32.ln());
- }
-
- #[test]
- pub fn test_abs() {
- assert_eq!(INFINITY.abs(), INFINITY);
- assert_eq!(1f32.abs(), 1f32);
- assert_eq!(0f32.abs(), 0f32);
- assert_eq!((-0f32).abs(), 0f32);
- assert_eq!((-1f32).abs(), 1f32);
- assert_eq!(NEG_INFINITY.abs(), INFINITY);
- assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
- assert!(NAN.abs().is_nan());
- }
-
- #[test]
- fn test_abs_sub() {
- assert_eq!((-1f32).abs_sub(&1f32), 0f32);
- assert_eq!(1f32.abs_sub(&1f32), 0f32);
- assert_eq!(1f32.abs_sub(&0f32), 1f32);
- assert_eq!(1f32.abs_sub(&-1f32), 2f32);
- assert_eq!(NEG_INFINITY.abs_sub(&0f32), 0f32);
- assert_eq!(INFINITY.abs_sub(&1f32), INFINITY);
- assert_eq!(0f32.abs_sub(&NEG_INFINITY), INFINITY);
- assert_eq!(0f32.abs_sub(&INFINITY), 0f32);
- }
-
- #[test] #[ignore(cfg(windows))] // FIXME #8663
- fn test_abs_sub_nowin() {
- assert!(NAN.abs_sub(&-1f32).is_nan());
- assert!(1f32.abs_sub(&NAN).is_nan());
- }
-
- #[test]
- fn test_signum() {
- assert_eq!(INFINITY.signum(), 1f32);
- assert_eq!(1f32.signum(), 1f32);
- assert_eq!(0f32.signum(), 1f32);
- assert_eq!((-0f32).signum(), -1f32);
- assert_eq!((-1f32).signum(), -1f32);
- assert_eq!(NEG_INFINITY.signum(), -1f32);
- assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
- assert!(NAN.signum().is_nan());
- }
-
- #[test]
- fn test_is_positive() {
- assert!(INFINITY.is_positive());
- assert!(1f32.is_positive());
- assert!(0f32.is_positive());
- assert!(!(-0f32).is_positive());
- assert!(!(-1f32).is_positive());
- assert!(!NEG_INFINITY.is_positive());
- assert!(!(1f32/NEG_INFINITY).is_positive());
- assert!(!NAN.is_positive());
- }
-
- #[test]
- fn test_is_negative() {
- assert!(!INFINITY.is_negative());
- assert!(!1f32.is_negative());
- assert!(!0f32.is_negative());
- assert!((-0f32).is_negative());
- assert!((-1f32).is_negative());
- assert!(NEG_INFINITY.is_negative());
- assert!((1f32/NEG_INFINITY).is_negative());
- assert!(!NAN.is_negative());
- }
-
- #[test]
- fn test_approx_eq() {
- assert!(1.0f32.approx_eq(&1f32));
- assert!(0.9999999f32.approx_eq(&1f32));
- assert!(1.000001f32.approx_eq_eps(&1f32, &1.0e-5));
- assert!(1.0000001f32.approx_eq_eps(&1f32, &1.0e-6));
- assert!(!1.0000001f32.approx_eq_eps(&1f32, &1.0e-7));
- }
-
- #[test]
- fn test_primitive() {
- let none: Option<f32> = None;
- assert_eq!(Primitive::bits(none), mem::size_of::<f32>() * 8);
- assert_eq!(Primitive::bytes(none), mem::size_of::<f32>());
- }
-
- #[test]
- fn test_is_normal() {
- let nan: f32 = Float::nan();
- let inf: f32 = Float::infinity();
- let neg_inf: f32 = Float::neg_infinity();
- let zero: f32 = Zero::zero();
- let neg_zero: f32 = Float::neg_zero();
- assert!(!nan.is_normal());
- assert!(!inf.is_normal());
- assert!(!neg_inf.is_normal());
- assert!(!zero.is_normal());
- assert!(!neg_zero.is_normal());
- assert!(1f32.is_normal());
- assert!(1e-37f32.is_normal());
- assert!(!1e-38f32.is_normal());
- }
-
- #[test]
- fn test_classify() {
- let nan: f32 = Float::nan();
- let inf: f32 = Float::infinity();
- let neg_inf: f32 = Float::neg_infinity();
- let zero: f32 = Zero::zero();
- let neg_zero: f32 = Float::neg_zero();
- assert_eq!(nan.classify(), FPNaN);
- assert_eq!(inf.classify(), FPInfinite);
- assert_eq!(neg_inf.classify(), FPInfinite);
- assert_eq!(zero.classify(), FPZero);
- assert_eq!(neg_zero.classify(), FPZero);
- assert_eq!(1f32.classify(), FPNormal);
- assert_eq!(1e-37f32.classify(), FPNormal);
- assert_eq!(1e-38f32.classify(), FPSubnormal);
- }
-
- #[test]
- fn test_ldexp() {
- // We have to use from_str until base-2 exponents
- // are supported in floating-point literals
- let f1: f32 = from_str_hex("1p-123").unwrap();
- let f2: f32 = from_str_hex("1p-111").unwrap();
- assert_eq!(Float::ldexp(1f32, -123), f1);
- assert_eq!(Float::ldexp(1f32, -111), f2);
-
- assert_eq!(Float::ldexp(0f32, -123), 0f32);
- assert_eq!(Float::ldexp(-0f32, -123), -0f32);
-
- let inf: f32 = Float::infinity();
- let neg_inf: f32 = Float::neg_infinity();
- let nan: f32 = Float::nan();
- assert_eq!(Float::ldexp(inf, -123), inf);
- assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
- assert!(Float::ldexp(nan, -123).is_nan());
- }
-
- #[test]
- fn test_frexp() {
- // We have to use from_str until base-2 exponents
- // are supported in floating-point literals
- let f1: f32 = from_str_hex("1p-123").unwrap();
- let f2: f32 = from_str_hex("1p-111").unwrap();
- let (x1, exp1) = f1.frexp();
- let (x2, exp2) = f2.frexp();
- assert_eq!((x1, exp1), (0.5f32, -122));
- assert_eq!((x2, exp2), (0.5f32, -110));
- assert_eq!(Float::ldexp(x1, exp1), f1);
- assert_eq!(Float::ldexp(x2, exp2), f2);
-
- assert_eq!(0f32.frexp(), (0f32, 0));
- assert_eq!((-0f32).frexp(), (-0f32, 0));
- }
-
- #[test] #[ignore(cfg(windows))] // FIXME #8755
- fn test_frexp_nowin() {
- let inf: f32 = Float::infinity();
- let neg_inf: f32 = Float::neg_infinity();
- let nan: f32 = Float::nan();
- assert_eq!(match inf.frexp() { (x, _) => x }, inf)
- assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
- assert!(match nan.frexp() { (x, _) => x.is_nan() })
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `f64`
-
-#[allow(missing_doc)];
-
-use default::Default;
-use libc::c_int;
-use num::{Zero, One, strconv};
-use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
-use num;
-use prelude::*;
-use to_str;
-
-pub use cmath::c_double_targ_consts::*;
-pub use cmp::{min, max};
-
-use self::delegated::*;
-
-macro_rules! delegate(
- (
- $(
- fn $name:ident(
- $(
- $arg:ident : $arg_ty:ty
- ),*
- ) -> $rv:ty = $bound_name:path
- ),*
- ) => (
- // An inner module is required to get the #[inline] attribute on the
- // functions.
- mod delegated {
- use cmath::c_double_utils;
- use libc::{c_double, c_int};
- use unstable::intrinsics;
-
- $(
- #[inline]
- pub fn $name($( $arg : $arg_ty ),*) -> $rv {
- unsafe {
- $bound_name($( $arg ),*)
- }
- }
- )*
- }
- )
-)
-
-delegate!(
- // intrinsics
- fn abs(n: f64) -> f64 = intrinsics::fabsf64,
- fn cos(n: f64) -> f64 = intrinsics::cosf64,
- fn exp(n: f64) -> f64 = intrinsics::expf64,
- fn exp2(n: f64) -> f64 = intrinsics::exp2f64,
- fn floor(x: f64) -> f64 = intrinsics::floorf64,
- fn ln(n: f64) -> f64 = intrinsics::logf64,
- fn log10(n: f64) -> f64 = intrinsics::log10f64,
- fn log2(n: f64) -> f64 = intrinsics::log2f64,
- fn mul_add(a: f64, b: f64, c: f64) -> f64 = intrinsics::fmaf64,
- fn pow(n: f64, e: f64) -> f64 = intrinsics::powf64,
- fn powi(n: f64, e: c_int) -> f64 = intrinsics::powif64,
- fn sin(n: f64) -> f64 = intrinsics::sinf64,
- fn sqrt(n: f64) -> f64 = intrinsics::sqrtf64,
-
- // LLVM 3.3 required to use intrinsics for these four
- fn ceil(n: c_double) -> c_double = c_double_utils::ceil,
- fn trunc(n: c_double) -> c_double = c_double_utils::trunc,
- /*
- fn ceil(n: f64) -> f64 = intrinsics::ceilf64,
- fn trunc(n: f64) -> f64 = intrinsics::truncf64,
- fn rint(n: c_double) -> c_double = intrinsics::rintf64,
- fn nearbyint(n: c_double) -> c_double = intrinsics::nearbyintf64,
- */
-
- // cmath
- fn acos(n: c_double) -> c_double = c_double_utils::acos,
- fn asin(n: c_double) -> c_double = c_double_utils::asin,
- fn atan(n: c_double) -> c_double = c_double_utils::atan,
- fn atan2(a: c_double, b: c_double) -> c_double = c_double_utils::atan2,
- fn cbrt(n: c_double) -> c_double = c_double_utils::cbrt,
- fn copysign(x: c_double, y: c_double) -> c_double = c_double_utils::copysign,
- fn cosh(n: c_double) -> c_double = c_double_utils::cosh,
- fn erf(n: c_double) -> c_double = c_double_utils::erf,
- fn erfc(n: c_double) -> c_double = c_double_utils::erfc,
- fn exp_m1(n: c_double) -> c_double = c_double_utils::exp_m1,
- fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub,
- fn next_after(x: c_double, y: c_double) -> c_double = c_double_utils::next_after,
- fn frexp(n: c_double, value: &mut c_int) -> c_double = c_double_utils::frexp,
- fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot,
- fn ldexp(x: c_double, n: c_int) -> c_double = c_double_utils::ldexp,
- fn lgamma(n: c_double, sign: &mut c_int) -> c_double = c_double_utils::lgamma,
- fn log_radix(n: c_double) -> c_double = c_double_utils::log_radix,
- fn ln_1p(n: c_double) -> c_double = c_double_utils::ln_1p,
- fn ilog_radix(n: c_double) -> c_int = c_double_utils::ilog_radix,
- fn modf(n: c_double, iptr: &mut c_double) -> c_double = c_double_utils::modf,
- fn round(n: c_double) -> c_double = c_double_utils::round,
- fn ldexp_radix(n: c_double, i: c_int) -> c_double = c_double_utils::ldexp_radix,
- fn sinh(n: c_double) -> c_double = c_double_utils::sinh,
- fn tan(n: c_double) -> c_double = c_double_utils::tan,
- fn tanh(n: c_double) -> c_double = c_double_utils::tanh,
- fn tgamma(n: c_double) -> c_double = c_double_utils::tgamma,
- fn j0(n: c_double) -> c_double = c_double_utils::j0,
- fn j1(n: c_double) -> c_double = c_double_utils::j1,
- fn jn(i: c_int, n: c_double) -> c_double = c_double_utils::jn,
- fn y0(n: c_double) -> c_double = c_double_utils::y0,
- fn y1(n: c_double) -> c_double = c_double_utils::y1,
- fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn
-)
-
-// FIXME (#1433): obtain these in a different way
-
-// These are not defined inside consts:: for consistency with
-// the integer types
-
-pub static RADIX: uint = 2u;
-
-pub static MANTISSA_DIGITS: uint = 53u;
-pub static DIGITS: uint = 15u;
-
-pub static EPSILON: f64 = 2.2204460492503131e-16_f64;
-
-pub static MIN_VALUE: f64 = 2.2250738585072014e-308_f64;
-pub static MAX_VALUE: f64 = 1.7976931348623157e+308_f64;
-
-pub static MIN_EXP: int = -1021;
-pub static MAX_EXP: int = 1024;
-
-pub static MIN_10_EXP: int = -307;
-pub static MAX_10_EXP: int = 308;
-
-pub static NAN: f64 = 0.0_f64/0.0_f64;
-
-pub static INFINITY: f64 = 1.0_f64/0.0_f64;
-
-pub static NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
-
-// FIXME (#1999): add is_normal, is_subnormal, and fpclassify
-
-/* Module: consts */
-pub mod consts {
- // FIXME (requires Issue #1433 to fix): replace with mathematical
- // constants from cmath.
- /// Archimedes' constant
- pub static PI: f64 = 3.14159265358979323846264338327950288_f64;
-
- /// pi/2.0
- pub static FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
-
- /// pi/4.0
- pub static FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64;
-
- /// 1.0/pi
- pub static FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
-
- /// 2.0/pi
- pub static FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64;
-
- /// 2.0/sqrt(pi)
- pub static FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64;
-
- /// sqrt(2.0)
- pub static SQRT2: f64 = 1.41421356237309504880168872420969808_f64;
-
- /// 1.0/sqrt(2.0)
- pub static FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64;
-
- /// Euler's number
- pub static E: f64 = 2.71828182845904523536028747135266250_f64;
-
- /// log2(e)
- pub static LOG2_E: f64 = 1.44269504088896340735992468100189214_f64;
-
- /// log10(e)
- pub static LOG10_E: f64 = 0.434294481903251827651128918916605082_f64;
-
- /// ln(2.0)
- pub static LN_2: f64 = 0.693147180559945309417232121458176568_f64;
-
- /// ln(10.0)
- pub static LN_10: f64 = 2.30258509299404568401799145468436421_f64;
-}
-
-impl Num for f64 {}
-
-#[cfg(not(test))]
-impl Eq for f64 {
- #[inline]
- fn eq(&self, other: &f64) -> bool { (*self) == (*other) }
-}
-
-#[cfg(not(test))]
-impl ApproxEq<f64> for f64 {
- #[inline]
- fn approx_epsilon() -> f64 { 1.0e-6 }
-
- #[inline]
- fn approx_eq(&self, other: &f64) -> bool {
- self.approx_eq_eps(other, &1.0e-6)
- }
-
- #[inline]
- fn approx_eq_eps(&self, other: &f64, approx_epsilon: &f64) -> bool {
- (*self - *other).abs() < *approx_epsilon
- }
-}
-
-#[cfg(not(test))]
-impl Ord for f64 {
- #[inline]
- fn lt(&self, other: &f64) -> bool { (*self) < (*other) }
- #[inline]
- fn le(&self, other: &f64) -> bool { (*self) <= (*other) }
- #[inline]
- fn ge(&self, other: &f64) -> bool { (*self) >= (*other) }
- #[inline]
- fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
-}
-
-impl Orderable for f64 {
- /// Returns `NAN` if either of the numbers are `NAN`.
- #[inline]
- fn min(&self, other: &f64) -> f64 {
- match () {
- _ if self.is_nan() => *self,
- _ if other.is_nan() => *other,
- _ if *self < *other => *self,
- _ => *other,
- }
- }
-
- /// Returns `NAN` if either of the numbers are `NAN`.
- #[inline]
- fn max(&self, other: &f64) -> f64 {
- match () {
- _ if self.is_nan() => *self,
- _ if other.is_nan() => *other,
- _ if *self > *other => *self,
- _ => *other,
- }
- }
-
- /// Returns the number constrained within the range `mn <= self <= mx`.
- /// If any of the numbers are `NAN` then `NAN` is returned.
- #[inline]
- fn clamp(&self, mn: &f64, mx: &f64) -> f64 {
- match () {
- _ if self.is_nan() => *self,
- _ if !(*self <= *mx) => *mx,
- _ if !(*self >= *mn) => *mn,
- _ => *self,
- }
- }
-}
-
-impl Default for f64 {
- #[inline]
- fn default() -> f64 { 0.0 }
-}
-
-impl Zero for f64 {
- #[inline]
- fn zero() -> f64 { 0.0 }
-
- /// Returns true if the number is equal to either `0.0` or `-0.0`
- #[inline]
- fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
-}
-
-impl One for f64 {
- #[inline]
- fn one() -> f64 { 1.0 }
-}
-
-#[cfg(not(test))]
-impl Add<f64,f64> for f64 {
- #[inline]
- fn add(&self, other: &f64) -> f64 { *self + *other }
-}
-#[cfg(not(test))]
-impl Sub<f64,f64> for f64 {
- #[inline]
- fn sub(&self, other: &f64) -> f64 { *self - *other }
-}
-#[cfg(not(test))]
-impl Mul<f64,f64> for f64 {
- #[inline]
- fn mul(&self, other: &f64) -> f64 { *self * *other }
-}
-#[cfg(not(test))]
-impl Div<f64,f64> for f64 {
- #[inline]
- fn div(&self, other: &f64) -> f64 { *self / *other }
-}
-#[cfg(not(test))]
-impl Rem<f64,f64> for f64 {
- #[inline]
- fn rem(&self, other: &f64) -> f64 { *self % *other }
-}
-#[cfg(not(test))]
-impl Neg<f64> for f64 {
- #[inline]
- fn neg(&self) -> f64 { -*self }
-}
-
-impl Signed for f64 {
- /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
- #[inline]
- fn abs(&self) -> f64 { abs(*self) }
-
- ///
- /// The positive difference of two numbers. Returns `0.0` if the number is less than or
- /// equal to `other`, otherwise the difference between`self` and `other` is returned.
- ///
- #[inline]
- fn abs_sub(&self, other: &f64) -> f64 { abs_sub(*self, *other) }
-
- ///
- /// # Returns
- ///
- /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
- /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
- /// - `NAN` if the number is NaN
- ///
- #[inline]
- fn signum(&self) -> f64 {
- if self.is_nan() { NAN } else { copysign(1.0, *self) }
- }
-
- /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
- #[inline]
- fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY }
-
- /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
- #[inline]
- fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
-}
-
-impl Round for f64 {
- /// Round half-way cases toward `NEG_INFINITY`
- #[inline]
- fn floor(&self) -> f64 { floor(*self) }
-
- /// Round half-way cases toward `INFINITY`
- #[inline]
- fn ceil(&self) -> f64 { ceil(*self) }
-
- /// Round half-way cases away from `0.0`
- #[inline]
- fn round(&self) -> f64 { round(*self) }
-
- /// The integer part of the number (rounds towards `0.0`)
- #[inline]
- fn trunc(&self) -> f64 { trunc(*self) }
-
- ///
- /// The fractional part of the number, satisfying:
- ///
- /// ```rust
- /// assert!(x == trunc(x) + fract(x))
- /// ```
- ///
- #[inline]
- fn fract(&self) -> f64 { *self - self.trunc() }
-}
-
-impl Fractional for f64 {
- /// The reciprocal (multiplicative inverse) of the number
- #[inline]
- fn recip(&self) -> f64 { 1.0 / *self }
-}
-
-impl Algebraic for f64 {
- #[inline]
- fn pow(&self, n: &f64) -> f64 { pow(*self, *n) }
-
- #[inline]
- fn sqrt(&self) -> f64 { sqrt(*self) }
-
- #[inline]
- fn rsqrt(&self) -> f64 { self.sqrt().recip() }
-
- #[inline]
- fn cbrt(&self) -> f64 { cbrt(*self) }
-
- #[inline]
- fn hypot(&self, other: &f64) -> f64 { hypot(*self, *other) }
-}
-
-impl Trigonometric for f64 {
- #[inline]
- fn sin(&self) -> f64 { sin(*self) }
-
- #[inline]
- fn cos(&self) -> f64 { cos(*self) }
-
- #[inline]
- fn tan(&self) -> f64 { tan(*self) }
-
- #[inline]
- fn asin(&self) -> f64 { asin(*self) }
-
- #[inline]
- fn acos(&self) -> f64 { acos(*self) }
-
- #[inline]
- fn atan(&self) -> f64 { atan(*self) }
-
- #[inline]
- fn atan2(&self, other: &f64) -> f64 { atan2(*self, *other) }
-
- /// Simultaneously computes the sine and cosine of the number
- #[inline]
- fn sin_cos(&self) -> (f64, f64) {
- (self.sin(), self.cos())
- }
-}
-
-impl Exponential for f64 {
- /// Returns the exponential of the number
- #[inline]
- fn exp(&self) -> f64 { exp(*self) }
-
- /// Returns 2 raised to the power of the number
- #[inline]
- fn exp2(&self) -> f64 { exp2(*self) }
-
- /// Returns the natural logarithm of the number
- #[inline]
- fn ln(&self) -> f64 { ln(*self) }
-
- /// Returns the logarithm of the number with respect to an arbitrary base
- #[inline]
- fn log(&self, base: &f64) -> f64 { self.ln() / base.ln() }
-
- /// Returns the base 2 logarithm of the number
- #[inline]
- fn log2(&self) -> f64 { log2(*self) }
-
- /// Returns the base 10 logarithm of the number
- #[inline]
- fn log10(&self) -> f64 { log10(*self) }
-}
-
-impl Hyperbolic for f64 {
- #[inline]
- fn sinh(&self) -> f64 { sinh(*self) }
-
- #[inline]
- fn cosh(&self) -> f64 { cosh(*self) }
-
- #[inline]
- fn tanh(&self) -> f64 { tanh(*self) }
-
- ///
- /// Inverse hyperbolic sine
- ///
- /// # Returns
- ///
- /// - on success, the inverse hyperbolic sine of `self` will be returned
- /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
- /// - `NAN` if `self` is `NAN`
- ///
- #[inline]
- fn asinh(&self) -> f64 {
- match *self {
- NEG_INFINITY => NEG_INFINITY,
- x => (x + ((x * x) + 1.0).sqrt()).ln(),
- }
- }
-
- ///
- /// Inverse hyperbolic cosine
- ///
- /// # Returns
- ///
- /// - on success, the inverse hyperbolic cosine of `self` will be returned
- /// - `INFINITY` if `self` is `INFINITY`
- /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
- ///
- #[inline]
- fn acosh(&self) -> f64 {
- match *self {
- x if x < 1.0 => Float::nan(),
- x => (x + ((x * x) - 1.0).sqrt()).ln(),
- }
- }
-
- ///
- /// Inverse hyperbolic tangent
- ///
- /// # Returns
- ///
- /// - on success, the inverse hyperbolic tangent of `self` will be returned
- /// - `self` if `self` is `0.0` or `-0.0`
- /// - `INFINITY` if `self` is `1.0`
- /// - `NEG_INFINITY` if `self` is `-1.0`
- /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
- /// (including `INFINITY` and `NEG_INFINITY`)
- ///
- #[inline]
- fn atanh(&self) -> f64 {
- 0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
- }
-}
-
-impl Real for f64 {
- /// Archimedes' constant
- #[inline]
- fn pi() -> f64 { 3.14159265358979323846264338327950288 }
-
- /// 2.0 * pi
- #[inline]
- fn two_pi() -> f64 { 6.28318530717958647692528676655900576 }
-
- /// pi / 2.0
- #[inline]
- fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 }
-
- /// pi / 3.0
- #[inline]
- fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 }
-
- /// pi / 4.0
- #[inline]
- fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 }
-
- /// pi / 6.0
- #[inline]
- fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 }
-
- /// pi / 8.0
- #[inline]
- fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 }
-
- /// 1.0 / pi
- #[inline]
- fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 }
-
- /// 2.0 / pi
- #[inline]
- fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 }
-
- /// 2.0 / sqrt(pi)
- #[inline]
- fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
-
- /// sqrt(2.0)
- #[inline]
- fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
-
- /// 1.0 / sqrt(2.0)
- #[inline]
- fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
-
- /// Euler's number
- #[inline]
- fn e() -> f64 { 2.71828182845904523536028747135266250 }
-
- /// log2(e)
- #[inline]
- fn log2_e() -> f64 { 1.44269504088896340735992468100189214 }
-
- /// log10(e)
- #[inline]
- fn log10_e() -> f64 { 0.434294481903251827651128918916605082 }
-
- /// ln(2.0)
- #[inline]
- fn ln_2() -> f64 { 0.693147180559945309417232121458176568 }
-
- /// ln(10.0)
- #[inline]
- fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
-
- /// Converts to degrees, assuming the number is in radians
- #[inline]
- fn to_degrees(&self) -> f64 { *self * (180.0f64 / Real::pi()) }
-
- /// Converts to radians, assuming the number is in degrees
- #[inline]
- fn to_radians(&self) -> f64 {
- let value: f64 = Real::pi();
- *self * (value / 180.0)
- }
-}
-
-impl RealExt for f64 {
- #[inline]
- fn lgamma(&self) -> (int, f64) {
- let mut sign = 0;
- let result = lgamma(*self, &mut sign);
- (sign as int, result)
- }
-
- #[inline]
- fn tgamma(&self) -> f64 { tgamma(*self) }
-
- #[inline]
- fn j0(&self) -> f64 { j0(*self) }
-
- #[inline]
- fn j1(&self) -> f64 { j1(*self) }
-
- #[inline]
- fn jn(&self, n: int) -> f64 { jn(n as c_int, *self) }
-
- #[inline]
- fn y0(&self) -> f64 { y0(*self) }
-
- #[inline]
- fn y1(&self) -> f64 { y1(*self) }
-
- #[inline]
- fn yn(&self, n: int) -> f64 { yn(n as c_int, *self) }
-}
-
-impl Bounded for f64 {
- #[inline]
- fn min_value() -> f64 { 2.2250738585072014e-308 }
-
- #[inline]
- fn max_value() -> f64 { 1.7976931348623157e+308 }
-}
-
-impl Primitive for f64 {
- #[inline]
- fn bits(_: Option<f64>) -> uint { 64 }
-
- #[inline]
- fn bytes(_: Option<f64>) -> uint { Primitive::bits(Some(0f64)) / 8 }
-
- #[inline]
- fn is_signed(_: Option<f64>) -> bool { true }
-}
-
-impl Float for f64 {
- #[inline]
- fn nan() -> f64 { 0.0 / 0.0 }
-
- #[inline]
- fn infinity() -> f64 { 1.0 / 0.0 }
-
- #[inline]
- fn neg_infinity() -> f64 { -1.0 / 0.0 }
-
- #[inline]
- fn neg_zero() -> f64 { -0.0 }
-
- /// Returns `true` if the number is NaN
- #[inline]
- fn is_nan(&self) -> bool { *self != *self }
-
- /// Returns `true` if the number is infinite
- #[inline]
- fn is_infinite(&self) -> bool {
- *self == Float::infinity() || *self == Float::neg_infinity()
- }
-
- /// Returns `true` if the number is neither infinite or NaN
- #[inline]
- fn is_finite(&self) -> bool {
- !(self.is_nan() || self.is_infinite())
- }
-
- /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
- #[inline]
- fn is_normal(&self) -> bool {
- self.classify() == FPNormal
- }
-
- /// Returns the floating point category of the number. If only one property is going to
- /// be tested, it is generally faster to use the specific predicate instead.
- fn classify(&self) -> FPCategory {
- static EXP_MASK: u64 = 0x7ff0000000000000;
- static MAN_MASK: u64 = 0x000fffffffffffff;
-
- match (
- unsafe { ::cast::transmute::<f64,u64>(*self) } & MAN_MASK,
- unsafe { ::cast::transmute::<f64,u64>(*self) } & EXP_MASK,
- ) {
- (0, 0) => FPZero,
- (_, 0) => FPSubnormal,
- (0, EXP_MASK) => FPInfinite,
- (_, EXP_MASK) => FPNaN,
- _ => FPNormal,
- }
- }
-
- #[inline]
- fn mantissa_digits(_: Option<f64>) -> uint { 53 }
-
- #[inline]
- fn digits(_: Option<f64>) -> uint { 15 }
-
- #[inline]
- fn epsilon() -> f64 { 2.2204460492503131e-16 }
-
- #[inline]
- fn min_exp(_: Option<f64>) -> int { -1021 }
-
- #[inline]
- fn max_exp(_: Option<f64>) -> int { 1024 }
-
- #[inline]
- fn min_10_exp(_: Option<f64>) -> int { -307 }
-
- #[inline]
- fn max_10_exp(_: Option<f64>) -> int { 308 }
-
- /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
- #[inline]
- fn ldexp(x: f64, exp: int) -> f64 {
- ldexp(x, exp as c_int)
- }
-
- ///
- /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
- ///
- /// - `self = x * pow(2, exp)`
- /// - `0.5 <= abs(x) < 1.0`
- ///
- #[inline]
- fn frexp(&self) -> (f64, int) {
- let mut exp = 0;
- let x = frexp(*self, &mut exp);
- (x, exp as int)
- }
-
- ///
- /// Returns the exponential of the number, minus `1`, in a way that is accurate
- /// even if the number is close to zero
- ///
- #[inline]
- fn exp_m1(&self) -> f64 { exp_m1(*self) }
-
- ///
- /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
- /// than if the operations were performed separately
- ///
- #[inline]
- fn ln_1p(&self) -> f64 { ln_1p(*self) }
-
- ///
- /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
- /// produces a more accurate result with better performance than a separate multiplication
- /// operation followed by an add.
- ///
- #[inline]
- fn mul_add(&self, a: f64, b: f64) -> f64 {
- mul_add(*self, a, b)
- }
-
- /// Returns the next representable floating-point value in the direction of `other`
- #[inline]
- fn next_after(&self, other: f64) -> f64 {
- next_after(*self, other)
- }
-}
-
-//
-// Section: String Conversions
-//
-
-///
-/// Converts a float to a string
-///
-/// # Arguments
-///
-/// * num - The float value
-///
-#[inline]
-pub fn to_str(num: f64) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 10u, true, strconv::SignNeg, strconv::DigAll);
- r
-}
-
-///
-/// Converts a float to a string in hexadecimal format
-///
-/// # Arguments
-///
-/// * num - The float value
-///
-#[inline]
-pub fn to_str_hex(num: f64) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 16u, true, strconv::SignNeg, strconv::DigAll);
- r
-}
-
-///
-/// Converts a float to a string in a given radix, and a flag indicating
-/// whether it's a special value
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * radix - The base to use
-///
-#[inline]
-pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
- strconv::float_to_str_common(num, rdx, true,
- strconv::SignNeg, strconv::DigAll)
-}
-
-///
-/// Converts a float to a string with exactly the number of
-/// provided significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-///
-#[inline]
-pub fn to_str_exact(num: f64, dig: uint) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
- r
-}
-
-///
-/// Converts a float to a string with a maximum number of
-/// significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-///
-#[inline]
-pub fn to_str_digits(num: f64, dig: uint) -> ~str {
- let (r, _) = strconv::float_to_str_common(
- num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
- r
-}
-
-impl to_str::ToStr for f64 {
- #[inline]
- fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
-}
-
-impl num::ToStrRadix for f64 {
- /// Converts a float to a string in a given radix
- ///
- /// # Arguments
- ///
- /// * num - The float value
- /// * radix - The base to use
- ///
- /// # Failure
- ///
- /// Fails if called on a special value like `inf`, `-inf` or `NAN` due to
- /// possible misinterpretation of the result at higher bases. If those values
- /// are expected, use `to_str_radix_special()` instead.
- #[inline]
- fn to_str_radix(&self, rdx: uint) -> ~str {
- let (r, special) = strconv::float_to_str_common(
- *self, rdx, true, strconv::SignNeg, strconv::DigAll);
- if special { fail!("number has a special value, \
- try to_str_radix_special() if those are expected") }
- r
- }
-}
-
-///
-/// Convert a string in base 16 to a float.
-/// Accepts a optional binary exponent.
-///
-/// This function accepts strings such as
-///
-/// * 'a4.fe'
-/// * '+a4.fe', equivalent to 'a4.fe'
-/// * '-a4.fe'
-/// * '2b.aP128', or equivalently, '2b.ap128'
-/// * '2b.aP-128'
-/// * '.' (understood as 0)
-/// * 'c.'
-/// * '.c', or, equivalently, '0.c'
-/// * '+inf', 'inf', '-inf', 'NaN'
-///
-/// Leading and trailing whitespace represent an error.
-///
-/// # Arguments
-///
-/// * num - A string
-///
-/// # Return value
-///
-/// `None` if the string did not represent a valid number. Otherwise,
-/// `Some(n)` where `n` is the floating-point number represented by `[num]`.
-///
-#[inline]
-pub fn from_str_hex(num: &str) -> Option<f64> {
- strconv::from_str_common(num, 16u, true, true, true,
- strconv::ExpBin, false, false)
-}
-
-impl FromStr for f64 {
- ///
- /// Convert a string in base 10 to a float.
- /// Accepts a optional decimal exponent.
- ///
- /// This function accepts strings such as
- ///
- /// * '3.14'
- /// * '+3.14', equivalent to '3.14'
- /// * '-3.14'
- /// * '2.5E10', or equivalently, '2.5e10'
- /// * '2.5E-10'
- /// * '.' (understood as 0)
- /// * '5.'
- /// * '.5', or, equivalently, '0.5'
- /// * '+inf', 'inf', '-inf', 'NaN'
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * num - A string
- ///
- /// # Return value
- ///
- /// `none` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `num`.
- ///
- #[inline]
- fn from_str(val: &str) -> Option<f64> {
- strconv::from_str_common(val, 10u, true, true, true,
- strconv::ExpDec, false, false)
- }
-}
-
-impl num::FromStrRadix for f64 {
- ///
- /// Convert a string in an given base to a float.
- ///
- /// Due to possible conflicts, this function does **not** accept
- /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
- /// does it recognize exponents of any kind.
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * num - A string
- /// * radix - The base to use. Must lie in the range [2 .. 36]
- ///
- /// # Return value
- ///
- /// `None` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `num`.
- ///
- #[inline]
- fn from_str_radix(val: &str, rdx: uint) -> Option<f64> {
- strconv::from_str_common(val, rdx, true, true, false,
- strconv::ExpNone, false, false)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use f64::*;
- use prelude::*;
-
- use num::*;
- use num;
- use mem;
-
- #[test]
- fn test_num() {
- num::test_num(10f64, 2f64);
- }
-
- #[test]
- fn test_min() {
- assert_eq!(1f64.min(&2f64), 1f64);
- assert_eq!(2f64.min(&1f64), 1f64);
-
- let nan: f64 = Float::nan();
- assert!(1f64.min(&nan).is_nan());
- assert!(nan.min(&1f64).is_nan());
- }
-
- #[test]
- fn test_max() {
- assert_eq!(1f64.max(&2f64), 2f64);
- assert_eq!(2f64.max(&1f64), 2f64);
-
- let nan: f64 = Float::nan();
- assert!(1f64.max(&nan).is_nan());
- assert!(nan.max(&1f64).is_nan());
- }
-
- #[test]
- fn test_clamp() {
- assert_eq!(1f64.clamp(&2f64, &4f64), 2f64);
- assert_eq!(8f64.clamp(&2f64, &4f64), 4f64);
- assert_eq!(3f64.clamp(&2f64, &4f64), 3f64);
-
- let nan: f64 = Float::nan();
- assert!(3f64.clamp(&nan, &4f64).is_nan());
- assert!(3f64.clamp(&2f64, &nan).is_nan());
- assert!(nan.clamp(&2f64, &4f64).is_nan());
- }
-
- #[test]
- fn test_floor() {
- assert_approx_eq!(1.0f64.floor(), 1.0f64);
- assert_approx_eq!(1.3f64.floor(), 1.0f64);
- assert_approx_eq!(1.5f64.floor(), 1.0f64);
- assert_approx_eq!(1.7f64.floor(), 1.0f64);
- assert_approx_eq!(0.0f64.floor(), 0.0f64);
- assert_approx_eq!((-0.0f64).floor(), -0.0f64);
- assert_approx_eq!((-1.0f64).floor(), -1.0f64);
- assert_approx_eq!((-1.3f64).floor(), -2.0f64);
- assert_approx_eq!((-1.5f64).floor(), -2.0f64);
- assert_approx_eq!((-1.7f64).floor(), -2.0f64);
- }
-
- #[test]
- fn test_ceil() {
- assert_approx_eq!(1.0f64.ceil(), 1.0f64);
- assert_approx_eq!(1.3f64.ceil(), 2.0f64);
- assert_approx_eq!(1.5f64.ceil(), 2.0f64);
- assert_approx_eq!(1.7f64.ceil(), 2.0f64);
- assert_approx_eq!(0.0f64.ceil(), 0.0f64);
- assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
- assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
- assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
- assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
- assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
- }
-
- #[test]
- fn test_round() {
- assert_approx_eq!(1.0f64.round(), 1.0f64);
- assert_approx_eq!(1.3f64.round(), 1.0f64);
- assert_approx_eq!(1.5f64.round(), 2.0f64);
- assert_approx_eq!(1.7f64.round(), 2.0f64);
- assert_approx_eq!(0.0f64.round(), 0.0f64);
- assert_approx_eq!((-0.0f64).round(), -0.0f64);
- assert_approx_eq!((-1.0f64).round(), -1.0f64);
- assert_approx_eq!((-1.3f64).round(), -1.0f64);
- assert_approx_eq!((-1.5f64).round(), -2.0f64);
- assert_approx_eq!((-1.7f64).round(), -2.0f64);
- }
-
- #[test]
- fn test_trunc() {
- assert_approx_eq!(1.0f64.trunc(), 1.0f64);
- assert_approx_eq!(1.3f64.trunc(), 1.0f64);
- assert_approx_eq!(1.5f64.trunc(), 1.0f64);
- assert_approx_eq!(1.7f64.trunc(), 1.0f64);
- assert_approx_eq!(0.0f64.trunc(), 0.0f64);
- assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
- assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
- assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
- assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
- assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
- }
-
- #[test]
- fn test_fract() {
- assert_approx_eq!(1.0f64.fract(), 0.0f64);
- assert_approx_eq!(1.3f64.fract(), 0.3f64);
- assert_approx_eq!(1.5f64.fract(), 0.5f64);
- assert_approx_eq!(1.7f64.fract(), 0.7f64);
- assert_approx_eq!(0.0f64.fract(), 0.0f64);
- assert_approx_eq!((-0.0f64).fract(), -0.0f64);
- assert_approx_eq!((-1.0f64).fract(), -0.0f64);
- assert_approx_eq!((-1.3f64).fract(), -0.3f64);
- assert_approx_eq!((-1.5f64).fract(), -0.5f64);
- assert_approx_eq!((-1.7f64).fract(), -0.7f64);
- }
-
- #[test]
- fn test_asinh() {
- assert_eq!(0.0f64.asinh(), 0.0f64);
- assert_eq!((-0.0f64).asinh(), -0.0f64);
-
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let nan: f64 = Float::nan();
- assert_eq!(inf.asinh(), inf);
- assert_eq!(neg_inf.asinh(), neg_inf);
- assert!(nan.asinh().is_nan());
- assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
- assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
- }
-
- #[test]
- fn test_acosh() {
- assert_eq!(1.0f64.acosh(), 0.0f64);
- assert!(0.999f64.acosh().is_nan());
-
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let nan: f64 = Float::nan();
- assert_eq!(inf.acosh(), inf);
- assert!(neg_inf.acosh().is_nan());
- assert!(nan.acosh().is_nan());
- assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
- assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
- }
-
- #[test]
- fn test_atanh() {
- assert_eq!(0.0f64.atanh(), 0.0f64);
- assert_eq!((-0.0f64).atanh(), -0.0f64);
-
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let nan: f64 = Float::nan();
- assert_eq!(1.0f64.atanh(), inf);
- assert_eq!((-1.0f64).atanh(), neg_inf);
- assert!(2f64.atanh().atanh().is_nan());
- assert!((-2f64).atanh().atanh().is_nan());
- assert!(inf.atanh().is_nan());
- assert!(neg_inf.atanh().is_nan());
- assert!(nan.atanh().is_nan());
- assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
- assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
- }
-
- #[test]
- fn test_real_consts() {
- let pi: f64 = Real::pi();
- let two_pi: f64 = Real::two_pi();
- let frac_pi_2: f64 = Real::frac_pi_2();
- let frac_pi_3: f64 = Real::frac_pi_3();
- let frac_pi_4: f64 = Real::frac_pi_4();
- let frac_pi_6: f64 = Real::frac_pi_6();
- let frac_pi_8: f64 = Real::frac_pi_8();
- let frac_1_pi: f64 = Real::frac_1_pi();
- let frac_2_pi: f64 = Real::frac_2_pi();
- let frac_2_sqrtpi: f64 = Real::frac_2_sqrtpi();
- let sqrt2: f64 = Real::sqrt2();
- let frac_1_sqrt2: f64 = Real::frac_1_sqrt2();
- let e: f64 = Real::e();
- let log2_e: f64 = Real::log2_e();
- let log10_e: f64 = Real::log10_e();
- let ln_2: f64 = Real::ln_2();
- let ln_10: f64 = Real::ln_10();
-
- assert_approx_eq!(two_pi, 2.0 * pi);
- assert_approx_eq!(frac_pi_2, pi / 2f64);
- assert_approx_eq!(frac_pi_3, pi / 3f64);
- assert_approx_eq!(frac_pi_4, pi / 4f64);
- assert_approx_eq!(frac_pi_6, pi / 6f64);
- assert_approx_eq!(frac_pi_8, pi / 8f64);
- assert_approx_eq!(frac_1_pi, 1f64 / pi);
- assert_approx_eq!(frac_2_pi, 2f64 / pi);
- assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
- assert_approx_eq!(sqrt2, 2f64.sqrt());
- assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
- assert_approx_eq!(log2_e, e.log2());
- assert_approx_eq!(log10_e, e.log10());
- assert_approx_eq!(ln_2, 2f64.ln());
- assert_approx_eq!(ln_10, 10f64.ln());
- }
-
- #[test]
- pub fn test_abs() {
- assert_eq!(INFINITY.abs(), INFINITY);
- assert_eq!(1f64.abs(), 1f64);
- assert_eq!(0f64.abs(), 0f64);
- assert_eq!((-0f64).abs(), 0f64);
- assert_eq!((-1f64).abs(), 1f64);
- assert_eq!(NEG_INFINITY.abs(), INFINITY);
- assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
- assert!(NAN.abs().is_nan());
- }
-
- #[test]
- fn test_abs_sub() {
- assert_eq!((-1f64).abs_sub(&1f64), 0f64);
- assert_eq!(1f64.abs_sub(&1f64), 0f64);
- assert_eq!(1f64.abs_sub(&0f64), 1f64);
- assert_eq!(1f64.abs_sub(&-1f64), 2f64);
- assert_eq!(NEG_INFINITY.abs_sub(&0f64), 0f64);
- assert_eq!(INFINITY.abs_sub(&1f64), INFINITY);
- assert_eq!(0f64.abs_sub(&NEG_INFINITY), INFINITY);
- assert_eq!(0f64.abs_sub(&INFINITY), 0f64);
- }
-
- #[test] #[ignore(cfg(windows))] // FIXME #8663
- fn test_abs_sub_nowin() {
- assert!(NAN.abs_sub(&-1f64).is_nan());
- assert!(1f64.abs_sub(&NAN).is_nan());
- }
-
- #[test]
- fn test_signum() {
- assert_eq!(INFINITY.signum(), 1f64);
- assert_eq!(1f64.signum(), 1f64);
- assert_eq!(0f64.signum(), 1f64);
- assert_eq!((-0f64).signum(), -1f64);
- assert_eq!((-1f64).signum(), -1f64);
- assert_eq!(NEG_INFINITY.signum(), -1f64);
- assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
- assert!(NAN.signum().is_nan());
- }
-
- #[test]
- fn test_is_positive() {
- assert!(INFINITY.is_positive());
- assert!(1f64.is_positive());
- assert!(0f64.is_positive());
- assert!(!(-0f64).is_positive());
- assert!(!(-1f64).is_positive());
- assert!(!NEG_INFINITY.is_positive());
- assert!(!(1f64/NEG_INFINITY).is_positive());
- assert!(!NAN.is_positive());
- }
-
- #[test]
- fn test_is_negative() {
- assert!(!INFINITY.is_negative());
- assert!(!1f64.is_negative());
- assert!(!0f64.is_negative());
- assert!((-0f64).is_negative());
- assert!((-1f64).is_negative());
- assert!(NEG_INFINITY.is_negative());
- assert!((1f64/NEG_INFINITY).is_negative());
- assert!(!NAN.is_negative());
- }
-
- #[test]
- fn test_approx_eq() {
- assert!(1.0f64.approx_eq(&1f64));
- assert!(0.9999999f64.approx_eq(&1f64));
- assert!(1.000001f64.approx_eq_eps(&1f64, &1.0e-5));
- assert!(1.0000001f64.approx_eq_eps(&1f64, &1.0e-6));
- assert!(!1.0000001f64.approx_eq_eps(&1f64, &1.0e-7));
- }
-
- #[test]
- fn test_primitive() {
- let none: Option<f64> = None;
- assert_eq!(Primitive::bits(none), mem::size_of::<f64>() * 8);
- assert_eq!(Primitive::bytes(none), mem::size_of::<f64>());
- }
-
- #[test]
- fn test_is_normal() {
- let nan: f64 = Float::nan();
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let zero: f64 = Zero::zero();
- let neg_zero: f64 = Float::neg_zero();
- assert!(!nan.is_normal());
- assert!(!inf.is_normal());
- assert!(!neg_inf.is_normal());
- assert!(!zero.is_normal());
- assert!(!neg_zero.is_normal());
- assert!(1f64.is_normal());
- assert!(1e-307f64.is_normal());
- assert!(!1e-308f64.is_normal());
- }
-
- #[test]
- fn test_classify() {
- let nan: f64 = Float::nan();
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let zero: f64 = Zero::zero();
- let neg_zero: f64 = Float::neg_zero();
- assert_eq!(nan.classify(), FPNaN);
- assert_eq!(inf.classify(), FPInfinite);
- assert_eq!(neg_inf.classify(), FPInfinite);
- assert_eq!(zero.classify(), FPZero);
- assert_eq!(neg_zero.classify(), FPZero);
- assert_eq!(1e-307f64.classify(), FPNormal);
- assert_eq!(1e-308f64.classify(), FPSubnormal);
- }
-
- #[test]
- fn test_ldexp() {
- // We have to use from_str until base-2 exponents
- // are supported in floating-point literals
- let f1: f64 = from_str_hex("1p-123").unwrap();
- let f2: f64 = from_str_hex("1p-111").unwrap();
- assert_eq!(Float::ldexp(1f64, -123), f1);
- assert_eq!(Float::ldexp(1f64, -111), f2);
-
- assert_eq!(Float::ldexp(0f64, -123), 0f64);
- assert_eq!(Float::ldexp(-0f64, -123), -0f64);
-
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let nan: f64 = Float::nan();
- assert_eq!(Float::ldexp(inf, -123), inf);
- assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
- assert!(Float::ldexp(nan, -123).is_nan());
- }
-
- #[test]
- fn test_frexp() {
- // We have to use from_str until base-2 exponents
- // are supported in floating-point literals
- let f1: f64 = from_str_hex("1p-123").unwrap();
- let f2: f64 = from_str_hex("1p-111").unwrap();
- let (x1, exp1) = f1.frexp();
- let (x2, exp2) = f2.frexp();
- assert_eq!((x1, exp1), (0.5f64, -122));
- assert_eq!((x2, exp2), (0.5f64, -110));
- assert_eq!(Float::ldexp(x1, exp1), f1);
- assert_eq!(Float::ldexp(x2, exp2), f2);
-
- assert_eq!(0f64.frexp(), (0f64, 0));
- assert_eq!((-0f64).frexp(), (-0f64, 0));
- }
-
- #[test] #[ignore(cfg(windows))] // FIXME #8755
- fn test_frexp_nowin() {
- let inf: f64 = Float::infinity();
- let neg_inf: f64 = Float::neg_infinity();
- let nan: f64 = Float::nan();
- assert_eq!(match inf.frexp() { (x, _) => x }, inf)
- assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
- assert!(match nan.frexp() { (x, _) => x.is_nan() })
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `i16`
-
-use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-int_module!(i16, 16)
-
-impl BitCount for i16 {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self) } }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self) } }
-}
-
-impl CheckedAdd for i16 {
- #[inline]
- fn checked_add(&self, v: &i16) -> Option<i16> {
- unsafe {
- let (x, y) = intrinsics::i16_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for i16 {
- #[inline]
- fn checked_sub(&self, v: &i16) -> Option<i16> {
- unsafe {
- let (x, y) = intrinsics::i16_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedMul for i16 {
- #[inline]
- fn checked_mul(&self, v: &i16) -> Option<i16> {
- unsafe {
- let (x, y) = intrinsics::i16_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `i32`
-
-use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-int_module!(i32, 32)
-
-impl BitCount for i32 {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self) } }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self) } }
-}
-
-impl CheckedAdd for i32 {
- #[inline]
- fn checked_add(&self, v: &i32) -> Option<i32> {
- unsafe {
- let (x, y) = intrinsics::i32_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for i32 {
- #[inline]
- fn checked_sub(&self, v: &i32) -> Option<i32> {
- unsafe {
- let (x, y) = intrinsics::i32_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedMul for i32 {
- #[inline]
- fn checked_mul(&self, v: &i32) -> Option<i32> {
- unsafe {
- let (x, y) = intrinsics::i32_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `i64`
-
-use num::{BitCount, CheckedAdd, CheckedSub};
-#[cfg(target_word_size = "64")]
-use num::CheckedMul;
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-int_module!(i64, 64)
-
-impl BitCount for i64 {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self) } }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self) } }
-}
-
-impl CheckedAdd for i64 {
- #[inline]
- fn checked_add(&self, v: &i64) -> Option<i64> {
- unsafe {
- let (x, y) = intrinsics::i64_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for i64 {
- #[inline]
- fn checked_sub(&self, v: &i64) -> Option<i64> {
- unsafe {
- let (x, y) = intrinsics::i64_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-// FIXME: #8449: should not be disabled on 32-bit
-#[cfg(target_word_size = "64")]
-impl CheckedMul for i64 {
- #[inline]
- fn checked_mul(&self, v: &i64) -> Option<i64> {
- unsafe {
- let (x, y) = intrinsics::i64_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `i8`
-
-use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-int_module!(i8, 8)
-
-impl BitCount for i8 {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self) } }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self) } }
-}
-
-impl CheckedAdd for i8 {
- #[inline]
- fn checked_add(&self, v: &i8) -> Option<i8> {
- unsafe {
- let (x, y) = intrinsics::i8_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for i8 {
- #[inline]
- fn checked_sub(&self, v: &i8) -> Option<i8> {
- unsafe {
- let (x, y) = intrinsics::i8_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedMul for i8 {
- #[inline]
- fn checked_mul(&self, v: &i8) -> Option<i8> {
- unsafe {
- let (x, y) = intrinsics::i8_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `int`
-
-#[allow(non_uppercase_statics)];
-
-use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-#[cfg(target_word_size = "32")] pub static bits: uint = 32;
-#[cfg(target_word_size = "64")] pub static bits: uint = 64;
-
-int_module!(int, super::bits)
-
-#[cfg(target_word_size = "32")]
-impl BitCount for int {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> int { (*self as i32).population_count() as int }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int }
-}
-
-#[cfg(target_word_size = "64")]
-impl BitCount for int {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> int { (*self as i64).population_count() as int }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedAdd for int {
- #[inline]
- fn checked_add(&self, v: &int) -> Option<int> {
- unsafe {
- let (x, y) = intrinsics::i32_add_with_overflow(*self as i32, *v as i32);
- if y { None } else { Some(x as int) }
- }
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedAdd for int {
- #[inline]
- fn checked_add(&self, v: &int) -> Option<int> {
- unsafe {
- let (x, y) = intrinsics::i64_add_with_overflow(*self as i64, *v as i64);
- if y { None } else { Some(x as int) }
- }
- }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedSub for int {
- #[inline]
- fn checked_sub(&self, v: &int) -> Option<int> {
- unsafe {
- let (x, y) = intrinsics::i32_sub_with_overflow(*self as i32, *v as i32);
- if y { None } else { Some(x as int) }
- }
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedSub for int {
- #[inline]
- fn checked_sub(&self, v: &int) -> Option<int> {
- unsafe {
- let (x, y) = intrinsics::i64_sub_with_overflow(*self as i64, *v as i64);
- if y { None } else { Some(x as int) }
- }
- }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedMul for int {
- #[inline]
- fn checked_mul(&self, v: &int) -> Option<int> {
- unsafe {
- let (x, y) = intrinsics::i32_mul_with_overflow(*self as i32, *v as i32);
- if y { None } else { Some(x as int) }
- }
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedMul for int {
- #[inline]
- fn checked_mul(&self, v: &int) -> Option<int> {
- unsafe {
- let (x, y) = intrinsics::i64_mul_with_overflow(*self as i64, *v as i64);
- if y { None } else { Some(x as int) }
- }
- }
-}
-
-/// Returns `base` raised to the power of `exponent`
-pub fn pow(base: int, exponent: uint) -> int {
- if exponent == 0u {
- //Not mathemtically true if ~[base == 0]
- return 1;
- }
- if base == 0 { return 0; }
- let mut my_pow = exponent;
- let mut acc = 1;
- let mut multiplier = base;
- while(my_pow > 0u) {
- if my_pow % 2u == 1u {
- acc *= multiplier;
- }
- my_pow /= 2u;
- multiplier *= multiplier;
- }
- return acc;
-}
-
-#[test]
-fn test_pow() {
- assert!((pow(0, 0u) == 1));
- assert!((pow(0, 1u) == 0));
- assert!((pow(0, 2u) == 0));
- assert!((pow(-1, 0u) == 1));
- assert!((pow(1, 0u) == 1));
- assert!((pow(-3, 2u) == 9));
- assert!((pow(-3, 3u) == -27));
- assert!((pow(4, 9u) == 262144));
-}
-
-#[test]
-fn test_overflows() {
- assert!((::int::max_value > 0));
- assert!((::int::min_value <= 0));
- assert!((::int::min_value + ::int::max_value + 1 == 0));
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// FIXME(#4375): this shouldn't have to be a nested module named 'generated'
-
-#[macro_escape];
-#[doc(hidden)];
-
-macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
-
-#[allow(non_uppercase_statics)];
-
-use default::Default;
-use num::{ToStrRadix, FromStrRadix};
-use num::{CheckedDiv, Zero, One, strconv};
-use prelude::*;
-use str;
-
-pub use cmp::{min, max};
-
-pub static bits : uint = $bits;
-pub static bytes : uint = ($bits / 8);
-
-pub static min_value: $T = (-1 as $T) << (bits - 1);
-// FIXME(#9837): Compute min_value like this so the high bits that shouldn't exist are 0.
-pub static max_value: $T = !min_value;
-
-impl CheckedDiv for $T {
- #[inline]
- fn checked_div(&self, v: &$T) -> Option<$T> {
- if *v == 0 || (*self == min_value && *v == -1) {
- None
- } else {
- Some(self / *v)
- }
- }
-}
-
-impl Num for $T {}
-
-#[cfg(not(test))]
-impl Ord for $T {
- #[inline]
- fn lt(&self, other: &$T) -> bool { return (*self) < (*other); }
-}
-
-#[cfg(not(test))]
-impl Eq for $T {
- #[inline]
- fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
-}
-
-impl Orderable for $T {
- #[inline]
- fn min(&self, other: &$T) -> $T {
- if *self < *other { *self } else { *other }
- }
-
- #[inline]
- fn max(&self, other: &$T) -> $T {
- if *self > *other { *self } else { *other }
- }
-
- #[inline]
- fn clamp(&self, mn: &$T, mx: &$T) -> $T {
- if *self > *mx { *mx } else
- if *self < *mn { *mn } else { *self }
- }
-}
-
-impl Default for $T {
- #[inline]
- fn default() -> $T { 0 }
-}
-
-impl Zero for $T {
- #[inline]
- fn zero() -> $T { 0 }
-
- #[inline]
- fn is_zero(&self) -> bool { *self == 0 }
-}
-
-impl One for $T {
- #[inline]
- fn one() -> $T { 1 }
-}
-
-#[cfg(not(test))]
-impl Add<$T,$T> for $T {
- #[inline]
- fn add(&self, other: &$T) -> $T { *self + *other }
-}
-
-#[cfg(not(test))]
-impl Sub<$T,$T> for $T {
- #[inline]
- fn sub(&self, other: &$T) -> $T { *self - *other }
-}
-
-#[cfg(not(test))]
-impl Mul<$T,$T> for $T {
- #[inline]
- fn mul(&self, other: &$T) -> $T { *self * *other }
-}
-
-#[cfg(not(test))]
-impl Div<$T,$T> for $T {
- ///
- /// Integer division, truncated towards 0. As this behaviour reflects the underlying
- /// machine implementation it is more efficient than `Integer::div_floor`.
- ///
- /// # Examples
- ///
- /// ```
- /// assert!( 8 / 3 == 2);
- /// assert!( 8 / -3 == -2);
- /// assert!(-8 / 3 == -2);
- /// assert!(-8 / -3 == 2);
-
- /// assert!( 1 / 2 == 0);
- /// assert!( 1 / -2 == 0);
- /// assert!(-1 / 2 == 0);
- /// assert!(-1 / -2 == 0);
- /// ```
- ///
- #[inline]
- fn div(&self, other: &$T) -> $T { *self / *other }
-}
-
-#[cfg(not(test))]
-impl Rem<$T,$T> for $T {
- ///
- /// Returns the integer remainder after division, satisfying:
- ///
- /// ```
- /// assert!((n / d) * d + (n % d) == n)
- /// ```
- ///
- /// # Examples
- ///
- /// ```
- /// assert!( 8 % 3 == 2);
- /// assert!( 8 % -3 == 2);
- /// assert!(-8 % 3 == -2);
- /// assert!(-8 % -3 == -2);
-
- /// assert!( 1 % 2 == 1);
- /// assert!( 1 % -2 == 1);
- /// assert!(-1 % 2 == -1);
- /// assert!(-1 % -2 == -1);
- /// ```
- ///
- #[inline]
- fn rem(&self, other: &$T) -> $T { *self % *other }
-}
-
-#[cfg(not(test))]
-impl Neg<$T> for $T {
- #[inline]
- fn neg(&self) -> $T { -*self }
-}
-
-impl Signed for $T {
- /// Computes the absolute value
- #[inline]
- fn abs(&self) -> $T {
- if self.is_negative() { -*self } else { *self }
- }
-
- ///
- /// The positive difference of two numbers. Returns `0` if the number is less than or
- /// equal to `other`, otherwise the difference between`self` and `other` is returned.
- ///
- #[inline]
- fn abs_sub(&self, other: &$T) -> $T {
- if *self <= *other { 0 } else { *self - *other }
- }
-
- ///
- /// # Returns
- ///
- /// - `0` if the number is zero
- /// - `1` if the number is positive
- /// - `-1` if the number is negative
- ///
- #[inline]
- fn signum(&self) -> $T {
- match *self {
- n if n > 0 => 1,
- 0 => 0,
- _ => -1,
- }
- }
-
- /// Returns true if the number is positive
- #[inline]
- fn is_positive(&self) -> bool { *self > 0 }
-
- /// Returns true if the number is negative
- #[inline]
- fn is_negative(&self) -> bool { *self < 0 }
-}
-
-impl Integer for $T {
- ///
- /// Floored integer division
- ///
- /// # Examples
- ///
- /// ```
- /// assert!(( 8).div_floor( 3) == 2);
- /// assert!(( 8).div_floor(-3) == -3);
- /// assert!((-8).div_floor( 3) == -3);
- /// assert!((-8).div_floor(-3) == 2);
- ///
- /// assert!(( 1).div_floor( 2) == 0);
- /// assert!(( 1).div_floor(-2) == -1);
- /// assert!((-1).div_floor( 2) == -1);
- /// assert!((-1).div_floor(-2) == 0);
- /// ```
- ///
- #[inline]
- fn div_floor(&self, other: &$T) -> $T {
- // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
- // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
- match self.div_rem(other) {
- (d, r) if (r > 0 && *other < 0)
- || (r < 0 && *other > 0) => d - 1,
- (d, _) => d,
- }
- }
-
- ///
- /// Integer modulo, satisfying:
- ///
- /// ```
- /// assert!(n.div_floor(d) * d + n.mod_floor(d) == n)
- /// ```
- ///
- /// # Examples
- ///
- /// ```
- /// assert!(( 8).mod_floor( 3) == 2);
- /// assert!(( 8).mod_floor(-3) == -1);
- /// assert!((-8).mod_floor( 3) == 1);
- /// assert!((-8).mod_floor(-3) == -2);
- ///
- /// assert!(( 1).mod_floor( 2) == 1);
- /// assert!(( 1).mod_floor(-2) == -1);
- /// assert!((-1).mod_floor( 2) == 1);
- /// assert!((-1).mod_floor(-2) == -1);
- /// ```
- ///
- #[inline]
- fn mod_floor(&self, other: &$T) -> $T {
- // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
- // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
- match *self % *other {
- r if (r > 0 && *other < 0)
- || (r < 0 && *other > 0) => r + *other,
- r => r,
- }
- }
-
- /// Calculates `div_floor` and `mod_floor` simultaneously
- #[inline]
- fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
- // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
- // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
- match self.div_rem(other) {
- (d, r) if (r > 0 && *other < 0)
- || (r < 0 && *other > 0) => (d - 1, r + *other),
- (d, r) => (d, r),
- }
- }
-
- /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
- #[inline]
- fn div_rem(&self, other: &$T) -> ($T,$T) {
- (*self / *other, *self % *other)
- }
-
- ///
- /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
- ///
- /// The result is always positive
- ///
- #[inline]
- fn gcd(&self, other: &$T) -> $T {
- // Use Euclid's algorithm
- let mut m = *self;
- let mut n = *other;
- while m != 0 {
- let temp = m;
- m = n % temp;
- n = temp;
- }
- n.abs()
- }
-
- ///
- /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
- ///
- #[inline]
- fn lcm(&self, other: &$T) -> $T {
- ((*self * *other) / self.gcd(other)).abs() // should not have to recaluculate abs
- }
-
- /// Returns `true` if the number can be divided by `other` without leaving a remainder
- #[inline]
- fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
-
- /// Returns `true` if the number is divisible by `2`
- #[inline]
- fn is_even(&self) -> bool { self.is_multiple_of(&2) }
-
- /// Returns `true` if the number is not divisible by `2`
- #[inline]
- fn is_odd(&self) -> bool { !self.is_even() }
-}
-
-impl Bitwise for $T {}
-
-#[cfg(not(test))]
-impl BitOr<$T,$T> for $T {
- #[inline]
- fn bitor(&self, other: &$T) -> $T { *self | *other }
-}
-
-#[cfg(not(test))]
-impl BitAnd<$T,$T> for $T {
- #[inline]
- fn bitand(&self, other: &$T) -> $T { *self & *other }
-}
-
-#[cfg(not(test))]
-impl BitXor<$T,$T> for $T {
- #[inline]
- fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
-}
-
-#[cfg(not(test))]
-impl Shl<$T,$T> for $T {
- #[inline]
- fn shl(&self, other: &$T) -> $T { *self << *other }
-}
-
-#[cfg(not(test))]
-impl Shr<$T,$T> for $T {
- #[inline]
- fn shr(&self, other: &$T) -> $T { *self >> *other }
-}
-
-#[cfg(not(test))]
-impl Not<$T> for $T {
- #[inline]
- fn not(&self) -> $T { !*self }
-}
-
-impl Bounded for $T {
- #[inline]
- fn min_value() -> $T { min_value }
-
- #[inline]
- fn max_value() -> $T { max_value }
-}
-
-impl Int for $T {}
-
-impl Primitive for $T {
- #[inline]
- fn bits(_: Option<$T>) -> uint { bits }
-
- #[inline]
- fn bytes(_: Option<$T>) -> uint { bits / 8 }
-
- #[inline]
- fn is_signed(_: Option<$T>) -> bool { true }
-}
-
-// String conversion functions and impl str -> num
-
-/// Parse a byte slice as a number in the given base.
-#[inline]
-pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
- strconv::from_str_bytes_common(buf, radix, true, false, false,
- strconv::ExpNone, false, false)
-}
-
-impl FromStr for $T {
- #[inline]
- fn from_str(s: &str) -> Option<$T> {
- strconv::from_str_common(s, 10u, true, false, false,
- strconv::ExpNone, false, false)
- }
-}
-
-impl FromStrRadix for $T {
- #[inline]
- fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
- strconv::from_str_common(s, radix, true, false, false,
- strconv::ExpNone, false, false)
- }
-}
-
-// String conversion functions and impl num -> str
-
-/// Convert to a string as a byte slice in a given base.
-#[inline]
-pub fn to_str_bytes<U>(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U {
- // The radix can be as low as 2, so we need at least 64 characters for a
- // base 2 number, and then we need another for a possible '-' character.
- let mut buf = [0u8, ..65];
- let mut cur = 0;
- strconv::int_to_str_bytes_common(n, radix, strconv::SignNeg, |i| {
- buf[cur] = i;
- cur += 1;
- });
- f(buf.slice(0, cur))
-}
-
-impl ToStr for $T {
- /// Convert to a string in base 10.
- #[inline]
- fn to_str(&self) -> ~str {
- self.to_str_radix(10)
- }
-}
-
-impl ToStrRadix for $T {
- /// Convert to a string in a given base.
- #[inline]
- fn to_str_radix(&self, radix: uint) -> ~str {
- let mut buf: ~[u8] = ~[];
- strconv::int_to_str_bytes_common(*self, radix, strconv::SignNeg, |i| {
- buf.push(i);
- });
- // We know we generated valid utf-8, so we don't need to go through that
- // check.
- unsafe { str::raw::from_utf8_owned(buf) }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use super::*;
-
- use int;
- use i32;
- use num;
- use mem;
-
- #[test]
- fn test_num() {
- num::test_num(10 as $T, 2 as $T);
- }
-
- #[test]
- fn test_orderable() {
- assert_eq!((1 as $T).min(&(2 as $T)), 1 as $T);
- assert_eq!((2 as $T).min(&(1 as $T)), 1 as $T);
- assert_eq!((1 as $T).max(&(2 as $T)), 2 as $T);
- assert_eq!((2 as $T).max(&(1 as $T)), 2 as $T);
- assert_eq!((1 as $T).clamp(&(2 as $T), &(4 as $T)), 2 as $T);
- assert_eq!((8 as $T).clamp(&(2 as $T), &(4 as $T)), 4 as $T);
- assert_eq!((3 as $T).clamp(&(2 as $T), &(4 as $T)), 3 as $T);
- }
-
- #[test]
- pub fn test_abs() {
- assert_eq!((1 as $T).abs(), 1 as $T);
- assert_eq!((0 as $T).abs(), 0 as $T);
- assert_eq!((-1 as $T).abs(), 1 as $T);
- }
-
- #[test]
- fn test_abs_sub() {
- assert_eq!((-1 as $T).abs_sub(&(1 as $T)), 0 as $T);
- assert_eq!((1 as $T).abs_sub(&(1 as $T)), 0 as $T);
- assert_eq!((1 as $T).abs_sub(&(0 as $T)), 1 as $T);
- assert_eq!((1 as $T).abs_sub(&(-1 as $T)), 2 as $T);
- }
-
- #[test]
- fn test_signum() {
- assert_eq!((1 as $T).signum(), 1 as $T);
- assert_eq!((0 as $T).signum(), 0 as $T);
- assert_eq!((-0 as $T).signum(), 0 as $T);
- assert_eq!((-1 as $T).signum(), -1 as $T);
- }
-
- #[test]
- fn test_is_positive() {
- assert!((1 as $T).is_positive());
- assert!(!(0 as $T).is_positive());
- assert!(!(-0 as $T).is_positive());
- assert!(!(-1 as $T).is_positive());
- }
-
- #[test]
- fn test_is_negative() {
- assert!(!(1 as $T).is_negative());
- assert!(!(0 as $T).is_negative());
- assert!(!(-0 as $T).is_negative());
- assert!((-1 as $T).is_negative());
- }
-
- ///
- /// Checks that the division rule holds for:
- ///
- /// - `n`: numerator (dividend)
- /// - `d`: denominator (divisor)
- /// - `qr`: quotient and remainder
- ///
- #[cfg(test)]
- fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
- assert_eq!(d * q + r, n);
- }
-
- #[test]
- fn test_div_rem() {
- fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
- let (n,d) = nd;
- let separate_div_rem = (n / d, n % d);
- let combined_div_rem = n.div_rem(&d);
-
- assert_eq!(separate_div_rem, qr);
- assert_eq!(combined_div_rem, qr);
-
- test_division_rule(nd, separate_div_rem);
- test_division_rule(nd, combined_div_rem);
- }
-
- test_nd_dr(( 8, 3), ( 2, 2));
- test_nd_dr(( 8, -3), (-2, 2));
- test_nd_dr((-8, 3), (-2, -2));
- test_nd_dr((-8, -3), ( 2, -2));
-
- test_nd_dr(( 1, 2), ( 0, 1));
- test_nd_dr(( 1, -2), ( 0, 1));
- test_nd_dr((-1, 2), ( 0, -1));
- test_nd_dr((-1, -2), ( 0, -1));
- }
-
- #[test]
- fn test_div_mod_floor() {
- fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
- let (n,d) = nd;
- let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
- let combined_div_mod_floor = n.div_mod_floor(&d);
-
- assert_eq!(separate_div_mod_floor, dm);
- assert_eq!(combined_div_mod_floor, dm);
-
- test_division_rule(nd, separate_div_mod_floor);
- test_division_rule(nd, combined_div_mod_floor);
- }
-
- test_nd_dm(( 8, 3), ( 2, 2));
- test_nd_dm(( 8, -3), (-3, -1));
- test_nd_dm((-8, 3), (-3, 1));
- test_nd_dm((-8, -3), ( 2, -2));
-
- test_nd_dm(( 1, 2), ( 0, 1));
- test_nd_dm(( 1, -2), (-1, -1));
- test_nd_dm((-1, 2), (-1, 1));
- test_nd_dm((-1, -2), ( 0, -1));
- }
-
- #[test]
- fn test_gcd() {
- assert_eq!((10 as $T).gcd(&2), 2 as $T);
- assert_eq!((10 as $T).gcd(&3), 1 as $T);
- assert_eq!((0 as $T).gcd(&3), 3 as $T);
- assert_eq!((3 as $T).gcd(&3), 3 as $T);
- assert_eq!((56 as $T).gcd(&42), 14 as $T);
- assert_eq!((3 as $T).gcd(&-3), 3 as $T);
- assert_eq!((-6 as $T).gcd(&3), 3 as $T);
- assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
- }
-
- #[test]
- fn test_lcm() {
- assert_eq!((1 as $T).lcm(&0), 0 as $T);
- assert_eq!((0 as $T).lcm(&1), 0 as $T);
- assert_eq!((1 as $T).lcm(&1), 1 as $T);
- assert_eq!((-1 as $T).lcm(&1), 1 as $T);
- assert_eq!((1 as $T).lcm(&-1), 1 as $T);
- assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
- assert_eq!((8 as $T).lcm(&9), 72 as $T);
- assert_eq!((11 as $T).lcm(&5), 55 as $T);
- }
-
- #[test]
- fn test_bitwise() {
- assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
- assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
- assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
- assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
- assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
- assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
- }
-
- #[test]
- fn test_multiple_of() {
- assert!((6 as $T).is_multiple_of(&(6 as $T)));
- assert!((6 as $T).is_multiple_of(&(3 as $T)));
- assert!((6 as $T).is_multiple_of(&(1 as $T)));
- assert!((-8 as $T).is_multiple_of(&(4 as $T)));
- assert!((8 as $T).is_multiple_of(&(-1 as $T)));
- assert!((-8 as $T).is_multiple_of(&(-2 as $T)));
- }
-
- #[test]
- fn test_even() {
- assert_eq!((-4 as $T).is_even(), true);
- assert_eq!((-3 as $T).is_even(), false);
- assert_eq!((-2 as $T).is_even(), true);
- assert_eq!((-1 as $T).is_even(), false);
- assert_eq!((0 as $T).is_even(), true);
- assert_eq!((1 as $T).is_even(), false);
- assert_eq!((2 as $T).is_even(), true);
- assert_eq!((3 as $T).is_even(), false);
- assert_eq!((4 as $T).is_even(), true);
- }
-
- #[test]
- fn test_odd() {
- assert_eq!((-4 as $T).is_odd(), false);
- assert_eq!((-3 as $T).is_odd(), true);
- assert_eq!((-2 as $T).is_odd(), false);
- assert_eq!((-1 as $T).is_odd(), true);
- assert_eq!((0 as $T).is_odd(), false);
- assert_eq!((1 as $T).is_odd(), true);
- assert_eq!((2 as $T).is_odd(), false);
- assert_eq!((3 as $T).is_odd(), true);
- assert_eq!((4 as $T).is_odd(), false);
- }
-
- #[test]
- fn test_bitcount() {
- assert_eq!((0b010101 as $T).population_count(), 3);
- }
-
- #[test]
- fn test_primitive() {
- let none: Option<$T> = None;
- assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8);
- assert_eq!(Primitive::bytes(none), mem::size_of::<$T>());
- }
-
- #[test]
- fn test_from_str() {
- assert_eq!(from_str::<$T>("0"), Some(0 as $T));
- assert_eq!(from_str::<$T>("3"), Some(3 as $T));
- assert_eq!(from_str::<$T>("10"), Some(10 as $T));
- assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
- assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
- assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
- assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
- assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
- assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
- assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
-
- assert!(from_str::<$T>(" ").is_none());
- assert!(from_str::<$T>("x").is_none());
- }
-
- #[test]
- fn test_parse_bytes() {
- use str::StrSlice;
- assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123 as $T));
- assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9 as $T));
- assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83 as $T));
- assert_eq!(i32::parse_bytes("123".as_bytes(), 16u), Some(291 as i32));
- assert_eq!(i32::parse_bytes("ffff".as_bytes(), 16u), Some(65535 as i32));
- assert_eq!(i32::parse_bytes("FFFF".as_bytes(), 16u), Some(65535 as i32));
- assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35 as $T));
- assert_eq!(parse_bytes("Z".as_bytes(), 36u), Some(35 as $T));
-
- assert_eq!(parse_bytes("-123".as_bytes(), 10u), Some(-123 as $T));
- assert_eq!(parse_bytes("-1001".as_bytes(), 2u), Some(-9 as $T));
- assert_eq!(parse_bytes("-123".as_bytes(), 8u), Some(-83 as $T));
- assert_eq!(i32::parse_bytes("-123".as_bytes(), 16u), Some(-291 as i32));
- assert_eq!(i32::parse_bytes("-ffff".as_bytes(), 16u), Some(-65535 as i32));
- assert_eq!(i32::parse_bytes("-FFFF".as_bytes(), 16u), Some(-65535 as i32));
- assert_eq!(parse_bytes("-z".as_bytes(), 36u), Some(-35 as $T));
- assert_eq!(parse_bytes("-Z".as_bytes(), 36u), Some(-35 as $T));
-
- assert!(parse_bytes("Z".as_bytes(), 35u).is_none());
- assert!(parse_bytes("-9".as_bytes(), 2u).is_none());
- }
-
- #[test]
- fn test_to_str() {
- assert_eq!((0 as $T).to_str_radix(10u), ~"0");
- assert_eq!((1 as $T).to_str_radix(10u), ~"1");
- assert_eq!((-1 as $T).to_str_radix(10u), ~"-1");
- assert_eq!((127 as $T).to_str_radix(16u), ~"7f");
- assert_eq!((100 as $T).to_str_radix(10u), ~"100");
-
- }
-
- #[test]
- fn test_int_to_str_overflow() {
- let mut i8_val: i8 = 127_i8;
- assert_eq!(i8_val.to_str(), ~"127");
-
- i8_val += 1 as i8;
- assert_eq!(i8_val.to_str(), ~"-128");
-
- let mut i16_val: i16 = 32_767_i16;
- assert_eq!(i16_val.to_str(), ~"32767");
-
- i16_val += 1 as i16;
- assert_eq!(i16_val.to_str(), ~"-32768");
-
- let mut i32_val: i32 = 2_147_483_647_i32;
- assert_eq!(i32_val.to_str(), ~"2147483647");
-
- i32_val += 1 as i32;
- assert_eq!(i32_val.to_str(), ~"-2147483648");
-
- let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
- assert_eq!(i64_val.to_str(), ~"9223372036854775807");
-
- i64_val += 1 as i64;
- assert_eq!(i64_val.to_str(), ~"-9223372036854775808");
- }
-
- #[test]
- fn test_int_from_str_overflow() {
- let mut i8_val: i8 = 127_i8;
- assert_eq!(from_str::<i8>("127"), Some(i8_val));
- assert!(from_str::<i8>("128").is_none());
-
- i8_val += 1 as i8;
- assert_eq!(from_str::<i8>("-128"), Some(i8_val));
- assert!(from_str::<i8>("-129").is_none());
-
- let mut i16_val: i16 = 32_767_i16;
- assert_eq!(from_str::<i16>("32767"), Some(i16_val));
- assert!(from_str::<i16>("32768").is_none());
-
- i16_val += 1 as i16;
- assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
- assert!(from_str::<i16>("-32769").is_none());
-
- let mut i32_val: i32 = 2_147_483_647_i32;
- assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
- assert!(from_str::<i32>("2147483648").is_none());
-
- i32_val += 1 as i32;
- assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
- assert!(from_str::<i32>("-2147483649").is_none());
-
- let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
- assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
- assert!(from_str::<i64>("9223372036854775808").is_none());
-
- i64_val += 1 as i64;
- assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
- assert!(from_str::<i64>("-9223372036854775809").is_none());
- }
-
- #[test]
- fn test_signed_checked_div() {
- assert_eq!(10i.checked_div(&2), Some(5));
- assert_eq!(5i.checked_div(&0), None);
- assert_eq!(int::min_value.checked_div(&-1), None);
- }
-}
-
-}))
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Numeric traits and functions for generic mathematics.
-//!
-//! These are implemented for the primitive numeric types in `std::{u8, u16,
-//! u32, u64, uint, i8, i16, i32, i64, int, f32, f64, float}`.
-
-#[allow(missing_doc)];
-
-use clone::{Clone, DeepClone};
-use cmp::{Eq, ApproxEq, Ord};
-use ops::{Add, Sub, Mul, Div, Rem, Neg};
-use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
-use option::{Option, Some, None};
-
-pub mod strconv;
-
-/// The base trait for numeric types
-pub trait Num: Eq + Zero + One
- + Neg<Self>
- + Add<Self,Self>
- + Sub<Self,Self>
- + Mul<Self,Self>
- + Div<Self,Self>
- + Rem<Self,Self> {}
-
-pub trait Orderable: Ord {
- // These should be methods on `Ord`, with overridable default implementations. We don't want
- // to encumber all implementors of Ord by requiring them to implement these functions, but at
- // the same time we want to be able to take advantage of the speed of the specific numeric
- // functions (like the `fmin` and `fmax` intrinsics).
- fn min(&self, other: &Self) -> Self;
- fn max(&self, other: &Self) -> Self;
- fn clamp(&self, mn: &Self, mx: &Self) -> Self;
-}
-
-/// Return the smaller number.
-#[inline(always)] pub fn min<T: Orderable>(x: T, y: T) -> T { x.min(&y) }
-/// Return the larger number.
-#[inline(always)] pub fn max<T: Orderable>(x: T, y: T) -> T { x.max(&y) }
-/// Returns the number constrained within the range `mn <= self <= mx`.
-#[inline(always)] pub fn clamp<T: Orderable>(value: T, mn: T, mx: T) -> T { value.clamp(&mn, &mx) }
-
-pub trait Zero {
- fn zero() -> Self; // FIXME (#5527): This should be an associated constant
- fn is_zero(&self) -> bool;
-}
-
-/// Returns `0` of appropriate type.
-#[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
-
-pub trait One {
- fn one() -> Self; // FIXME (#5527): This should be an associated constant
-}
-
-/// Returns `1` of appropriate type.
-#[inline(always)] pub fn one<T: One>() -> T { One::one() }
-
-pub trait Signed: Num
- + Neg<Self> {
- fn abs(&self) -> Self;
- fn abs_sub(&self, other: &Self) -> Self;
- fn signum(&self) -> Self;
-
- fn is_positive(&self) -> bool;
- fn is_negative(&self) -> bool;
-}
-
-/// Computes the absolute value.
-///
-/// For float, f32, and f64, `NaN` will be returned if the number is `NaN`
-#[inline(always)] pub fn abs<T: Signed>(value: T) -> T { value.abs() }
-/// The positive difference of two numbers.
-///
-/// Returns `zero` if the number is less than or equal to `other`,
-/// otherwise the difference between `self` and `other` is returned.
-#[inline(always)] pub fn abs_sub<T: Signed>(x: T, y: T) -> T { x.abs_sub(&y) }
-/// Returns the sign of the number.
-///
-/// For float, f32, f64:
-/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
-/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-/// - `NAN` if the number is `NAN`
-///
-/// For int:
-/// - `0` if the number is zero
-/// - `1` if the number is positive
-/// - `-1` if the number is negative
-#[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
-
-pub trait Unsigned: Num {}
-
-/// Times trait
-///
-/// ```rust
-/// use num::Times;
-/// let ten = 10 as uint;
-/// let mut accum = 0;
-/// ten.times(|| { accum += 1; })
-/// ```
-///
-pub trait Times {
- fn times(&self, it: ||);
-}
-
-pub trait Integer: Num
- + Orderable
- + Div<Self,Self>
- + Rem<Self,Self> {
- fn div_rem(&self, other: &Self) -> (Self,Self);
-
- fn div_floor(&self, other: &Self) -> Self;
- fn mod_floor(&self, other: &Self) -> Self;
- fn div_mod_floor(&self, other: &Self) -> (Self,Self);
-
- fn gcd(&self, other: &Self) -> Self;
- fn lcm(&self, other: &Self) -> Self;
-
- fn is_multiple_of(&self, other: &Self) -> bool;
- fn is_even(&self) -> bool;
- fn is_odd(&self) -> bool;
-}
-
-/// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
-///
-/// The result is always positive.
-#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
-/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
-#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
-
-/// A collection of rounding operations.
-pub trait Round {
- /// Return the largest integer less than or equal to a number.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_approx_eq!(1.3f32.floor(), 1.0);
- /// assert_approx_eq!((-1.3f32).floor(), -2.0);
- /// ```
- fn floor(&self) -> Self;
-
- /// Return the smallest integer greater than or equal to a number.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_approx_eq!(1.3f32.ceil(), 2.0);
- /// assert_approx_eq!((-1.3f32).ceil(), -1.0);
- /// ```
- fn ceil(&self) -> Self;
-
- /// Return the nearest integer to a number. Round half-way cases away from
- /// `0.0`.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_approx_eq!(1.3f32.round(), 1.0);
- /// assert_approx_eq!((-1.3f32).round(), -1.0);
- /// assert_approx_eq!(1.5f32.round(), 2.0);
- /// assert_approx_eq!((-1.5f32).round(), -2.0);
- /// ```
- fn round(&self) -> Self;
-
- /// Return the integer part of a number.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_approx_eq!(1.3f32.round(), 1.0);
- /// assert_approx_eq!((-1.3f32).round(), -1.0);
- /// assert_approx_eq!(1.5f32.round(), 1.0);
- /// assert_approx_eq!((-1.5f32).round(), -1.0);
- /// ```
- fn trunc(&self) -> Self;
-
- /// Return the fractional part of a number.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_approx_eq!(1.3f32.round(), 0.3);
- /// assert_approx_eq!((-1.3f32).round(), -0.3);
- /// assert_approx_eq!(1.5f32.round(), 0.5);
- /// assert_approx_eq!((-1.5f32).round(), -0.5);
- /// ```
- fn fract(&self) -> Self;
-}
-
-/// Trait for common fractional operations.
-pub trait Fractional: Num
- + Orderable
- + Round
- + Div<Self,Self> {
- /// Take the reciprocal (inverse) of a number, `1/x`.
- fn recip(&self) -> Self;
-}
-
-/// A collection of algebraic operations.
-pub trait Algebraic {
- /// Raise a number to a power.
- fn pow(&self, n: &Self) -> Self;
- /// Take the squre root of a number.
- fn sqrt(&self) -> Self;
- /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
- fn rsqrt(&self) -> Self;
- /// Take the cubic root of a number.
- fn cbrt(&self) -> Self;
- /// Calculate the length of the hypotenuse of a right-angle triangle given
- /// legs of length `x` and `y`.
- fn hypot(&self, other: &Self) -> Self;
-}
-
-/// Raise a number to a power.
-///
-/// # Example
-///
-/// ```rust
-/// let sixteen: float = num::pow(2.0, 4.0);
-/// assert_eq!(sixteen, 16.0);
-/// ```
-#[inline(always)] pub fn pow<T: Algebraic>(value: T, n: T) -> T { value.pow(&n) }
-/// Take the squre root of a number.
-#[inline(always)] pub fn sqrt<T: Algebraic>(value: T) -> T { value.sqrt() }
-/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
-#[inline(always)] pub fn rsqrt<T: Algebraic>(value: T) -> T { value.rsqrt() }
-/// Take the cubic root of a number.
-#[inline(always)] pub fn cbrt<T: Algebraic>(value: T) -> T { value.cbrt() }
-/// Calculate the length of the hypotenuse of a right-angle triangle given legs of length `x` and
-/// `y`.
-#[inline(always)] pub fn hypot<T: Algebraic>(x: T, y: T) -> T { x.hypot(&y) }
-
-/// A trait for trigonometric functions.
-pub trait Trigonometric {
- /// Computes the sine of a number (in radians).
- fn sin(&self) -> Self;
- /// Computes the cosine of a number (in radians).
- fn cos(&self) -> Self;
- /// Computes the tangent of a number (in radians).
- fn tan(&self) -> Self;
-
- /// Computes the arcsine of a number. Return value is in radians in
- /// the range [-pi/2, pi/2] or NaN if the number is outside the range
- /// [-1, 1].
- fn asin(&self) -> Self;
- /// Computes the arccosine of a number. Return value is in radians in
- /// the range [0, pi] or NaN if the number is outside the range
- /// [-1, 1].
- fn acos(&self) -> Self;
- /// Computes the arctangent of a number. Return value is in radians in the
- /// range [-pi/2, pi/2];
- fn atan(&self) -> Self;
-
- /// Computes the four quadrant arctangent of a number, `y`, and another
- /// number `x`. Return value is in radians in the range [-pi, pi];
- ///
- /// # Example
- ///
- /// ```rust
- /// let y = 3f32.sqrt();
- /// let x = 1f32;
- /// assert_approx_eq!(y.atan2(&x), f32::consts::PI / 3f32);
- /// assert_approx_eq!((-y).atan2(&(-x)), - 2f32 * f32::consts::PI / 3f32);
- /// ```
- fn atan2(&self, other: &Self) -> Self;
-
- /// Simultaneously computes the sine and cosine of the number, `x`. Returns
- /// `(sin(x), cos(x))`.
- fn sin_cos(&self) -> (Self, Self);
-}
-
-/// Sine function.
-#[inline(always)] pub fn sin<T: Trigonometric>(value: T) -> T { value.sin() }
-/// Cosine function.
-#[inline(always)] pub fn cos<T: Trigonometric>(value: T) -> T { value.cos() }
-/// Tangent function.
-#[inline(always)] pub fn tan<T: Trigonometric>(value: T) -> T { value.tan() }
-
-/// Compute the arcsine of the number.
-#[inline(always)] pub fn asin<T: Trigonometric>(value: T) -> T { value.asin() }
-/// Compute the arccosine of the number.
-#[inline(always)] pub fn acos<T: Trigonometric>(value: T) -> T { value.acos() }
-/// Compute the arctangent of the number.
-#[inline(always)] pub fn atan<T: Trigonometric>(value: T) -> T { value.atan() }
-
-/// Compute the arctangent with 2 arguments.
-#[inline(always)] pub fn atan2<T: Trigonometric>(x: T, y: T) -> T { x.atan2(&y) }
-/// Simultaneously computes the sine and cosine of the number.
-#[inline(always)] pub fn sin_cos<T: Trigonometric>(value: T) -> (T, T) { value.sin_cos() }
-
-/// A trait exponential functions.
-pub trait Exponential {
- /// Returns `e^(self)`, (the exponential function).
- fn exp(&self) -> Self;
- /// Returns 2 raised to the power of the number, `2^(self)`.
- fn exp2(&self) -> Self;
-
- /// Returns the natural logarithm of the number.
- fn ln(&self) -> Self;
- /// Returns the logarithm of the number with respect to an arbitrary base.
- fn log(&self, base: &Self) -> Self;
- /// Returns the base 2 logarithm of the number.
- fn log2(&self) -> Self;
- /// Returns the base 10 logarithm of the number.
- fn log10(&self) -> Self;
-}
-
-/// Returns `e^(value)`, (the exponential function).
-#[inline(always)] pub fn exp<T: Exponential>(value: T) -> T { value.exp() }
-/// Returns 2 raised to the power of the number, `2^(value)`.
-#[inline(always)] pub fn exp2<T: Exponential>(value: T) -> T { value.exp2() }
-
-/// Returns the natural logarithm of the number.
-#[inline(always)] pub fn ln<T: Exponential>(value: T) -> T { value.ln() }
-/// Returns the logarithm of the number with respect to an arbitrary base.
-#[inline(always)] pub fn log<T: Exponential>(value: T, base: T) -> T { value.log(&base) }
-/// Returns the base 2 logarithm of the number.
-#[inline(always)] pub fn log2<T: Exponential>(value: T) -> T { value.log2() }
-/// Returns the base 10 logarithm of the number.
-#[inline(always)] pub fn log10<T: Exponential>(value: T) -> T { value.log10() }
-
-/// A trait hyperbolic functions.
-pub trait Hyperbolic: Exponential {
- /// Hyperbolic sine function.
- fn sinh(&self) -> Self;
- /// Hyperbolic cosine function.
- fn cosh(&self) -> Self;
- /// Hyperbolic tangent function.
- fn tanh(&self) -> Self;
-
- /// Inverse hyperbolic sine function.
- fn asinh(&self) -> Self;
- /// Inverse hyperbolic cosine function.
- fn acosh(&self) -> Self;
- /// Inverse hyperbolic tangent function.
- fn atanh(&self) -> Self;
-}
-
-/// Hyperbolic sine function.
-#[inline(always)] pub fn sinh<T: Hyperbolic>(value: T) -> T { value.sinh() }
-/// Hyperbolic cosine function.
-#[inline(always)] pub fn cosh<T: Hyperbolic>(value: T) -> T { value.cosh() }
-/// Hyperbolic tangent function.
-#[inline(always)] pub fn tanh<T: Hyperbolic>(value: T) -> T { value.tanh() }
-
-/// Inverse hyperbolic sine function.
-#[inline(always)] pub fn asinh<T: Hyperbolic>(value: T) -> T { value.asinh() }
-/// Inverse hyperbolic cosine function.
-#[inline(always)] pub fn acosh<T: Hyperbolic>(value: T) -> T { value.acosh() }
-/// Inverse hyperbolic tangent function.
-#[inline(always)] pub fn atanh<T: Hyperbolic>(value: T) -> T { value.atanh() }
-
-/// Defines constants and methods common to real numbers
-pub trait Real: Signed
- + Fractional
- + Algebraic
- + Trigonometric
- + Hyperbolic {
- // Common Constants
- // FIXME (#5527): These should be associated constants
- fn pi() -> Self;
- fn two_pi() -> Self;
- fn frac_pi_2() -> Self;
- fn frac_pi_3() -> Self;
- fn frac_pi_4() -> Self;
- fn frac_pi_6() -> Self;
- fn frac_pi_8() -> Self;
- fn frac_1_pi() -> Self;
- fn frac_2_pi() -> Self;
- fn frac_2_sqrtpi() -> Self;
- fn sqrt2() -> Self;
- fn frac_1_sqrt2() -> Self;
- fn e() -> Self;
- fn log2_e() -> Self;
- fn log10_e() -> Self;
- fn ln_2() -> Self;
- fn ln_10() -> Self;
-
- // Angular conversions
-
- /// Convert radians to degrees.
- fn to_degrees(&self) -> Self;
- /// Convert degrees to radians.
- fn to_radians(&self) -> Self;
-}
-
-/// Methods that are harder to implement and not commonly used.
-pub trait RealExt: Real {
- // FIXME (#5527): usages of `int` should be replaced with an associated
- // integer type once these are implemented
-
- // Gamma functions
- fn lgamma(&self) -> (int, Self);
- fn tgamma(&self) -> Self;
-
- // Bessel functions
- fn j0(&self) -> Self;
- fn j1(&self) -> Self;
- fn jn(&self, n: int) -> Self;
- fn y0(&self) -> Self;
- fn y1(&self) -> Self;
- fn yn(&self, n: int) -> Self;
-}
-
-/// Collects the bitwise operators under one trait.
-pub trait Bitwise: Not<Self>
- + BitAnd<Self,Self>
- + BitOr<Self,Self>
- + BitXor<Self,Self>
- + Shl<Self,Self>
- + Shr<Self,Self> {}
-
-/// A trait for common counting operations on bits.
-pub trait BitCount {
- /// Returns the number of bits set in the number.
- ///
- /// # Example
- ///
- /// ```rust
- /// let n = 0b0101000u16;
- /// assert_eq!(n.population_count(), 2);
- /// ```
- fn population_count(&self) -> Self;
- /// Returns the number of leading zeros in the number.
- ///
- /// # Example
- ///
- /// ```rust
- /// let n = 0b0101000u16;
- /// assert_eq!(n.leading_zeros(), 10);
- /// ```
- fn leading_zeros(&self) -> Self;
- /// Returns the number of trailing zeros in the number.
- ///
- /// # Example
- ///
- /// ```rust
- /// let n = 0b0101000u16;
- /// assert_eq!(n.trailing_zeros(), 3);
- /// ```
- fn trailing_zeros(&self) -> Self;
-}
-
-pub trait Bounded {
- // FIXME (#5527): These should be associated constants
- fn min_value() -> Self;
- fn max_value() -> Self;
-}
-
-/// Specifies the available operations common to all of Rust's core numeric primitives.
-/// These may not always make sense from a purely mathematical point of view, but
-/// may be useful for systems programming.
-pub trait Primitive: Clone
- + DeepClone
- + Num
- + NumCast
- + Orderable
- + Bounded
- + Neg<Self>
- + Add<Self,Self>
- + Sub<Self,Self>
- + Mul<Self,Self>
- + Div<Self,Self>
- + Rem<Self,Self> {
- // FIXME (#5527): These should be associated constants
- // FIXME (#8888): Removing `unused_self` requires #8888 to be fixed.
- fn bits(unused_self: Option<Self>) -> uint;
- fn bytes(unused_self: Option<Self>) -> uint;
- fn is_signed(unused_self: Option<Self>) -> bool;
-}
-
-/// A collection of traits relevant to primitive signed and unsigned integers
-pub trait Int: Integer
- + Primitive
- + Bitwise
- + BitCount {}
-
-/// Used for representing the classification of floating point numbers
-#[deriving(Eq)]
-pub enum FPCategory {
- /// "Not a Number", often obtained by dividing by zero
- FPNaN,
- /// Positive or negative infinity
- FPInfinite ,
- /// Positive or negative zero
- FPZero,
- /// De-normalized floating point representation (less precise than `FPNormal`)
- FPSubnormal,
- /// A regular floating point number
- FPNormal,
-}
-
-/// Primitive floating point numbers
-pub trait Float: Real
- + Signed
- + Primitive
- + ApproxEq<Self> {
- // FIXME (#5527): These should be associated constants
- fn nan() -> Self;
- fn infinity() -> Self;
- fn neg_infinity() -> Self;
- fn neg_zero() -> Self;
-
- fn is_nan(&self) -> bool;
- fn is_infinite(&self) -> bool;
- fn is_finite(&self) -> bool;
- fn is_normal(&self) -> bool;
- fn classify(&self) -> FPCategory;
-
- // FIXME (#8888): Removing `unused_self` requires #8888 to be fixed.
- fn mantissa_digits(unused_self: Option<Self>) -> uint;
- fn digits(unused_self: Option<Self>) -> uint;
- fn epsilon() -> Self;
- fn min_exp(unused_self: Option<Self>) -> int;
- fn max_exp(unused_self: Option<Self>) -> int;
- fn min_10_exp(unused_self: Option<Self>) -> int;
- fn max_10_exp(unused_self: Option<Self>) -> int;
-
- fn ldexp(x: Self, exp: int) -> Self;
- fn frexp(&self) -> (Self, int);
-
- fn exp_m1(&self) -> Self;
- fn ln_1p(&self) -> Self;
- fn mul_add(&self, a: Self, b: Self) -> Self;
- fn next_after(&self, other: Self) -> Self;
-}
-
-/// Returns the exponential of the number, minus `1`, `exp(n) - 1`, in a way
-/// that is accurate even if the number is close to zero.
-#[inline(always)] pub fn exp_m1<T: Float>(value: T) -> T { value.exp_m1() }
-/// Returns the natural logarithm of the number plus `1`, `ln(n + 1)`, more
-/// accurately than if the operations were performed separately.
-#[inline(always)] pub fn ln_1p<T: Float>(value: T) -> T { value.ln_1p() }
-/// Fused multiply-add. Computes `(a * b) + c` with only one rounding error.
-///
-/// This produces a more accurate result with better performance (on some
-/// architectures) than a separate multiplication operation followed by an add.
-#[inline(always)] pub fn mul_add<T: Float>(a: T, b: T, c: T) -> T { a.mul_add(b, c) }
-
-/// A generic trait for converting a value to a number.
-pub trait ToPrimitive {
- /// Converts the value of `self` to an `int`.
- #[inline]
- fn to_int(&self) -> Option<int> {
- self.to_i64().and_then(|x| x.to_int())
- }
-
- /// Converts the value of `self` to an `i8`.
- #[inline]
- fn to_i8(&self) -> Option<i8> {
- self.to_i64().and_then(|x| x.to_i8())
- }
-
- /// Converts the value of `self` to an `i16`.
- #[inline]
- fn to_i16(&self) -> Option<i16> {
- self.to_i64().and_then(|x| x.to_i16())
- }
-
- /// Converts the value of `self` to an `i32`.
- #[inline]
- fn to_i32(&self) -> Option<i32> {
- self.to_i64().and_then(|x| x.to_i32())
- }
-
- /// Converts the value of `self` to an `i64`.
- fn to_i64(&self) -> Option<i64>;
-
- /// Converts the value of `self` to an `uint`.
- #[inline]
- fn to_uint(&self) -> Option<uint> {
- self.to_u64().and_then(|x| x.to_uint())
- }
-
- /// Converts the value of `self` to an `u8`.
- #[inline]
- fn to_u8(&self) -> Option<u8> {
- self.to_u64().and_then(|x| x.to_u8())
- }
-
- /// Converts the value of `self` to an `u16`.
- #[inline]
- fn to_u16(&self) -> Option<u16> {
- self.to_u64().and_then(|x| x.to_u16())
- }
-
- /// Converts the value of `self` to an `u32`.
- #[inline]
- fn to_u32(&self) -> Option<u32> {
- self.to_u64().and_then(|x| x.to_u32())
- }
-
- /// Converts the value of `self` to an `u64`.
- #[inline]
- fn to_u64(&self) -> Option<u64>;
-
- /// Converts the value of `self` to an `f32`.
- #[inline]
- fn to_f32(&self) -> Option<f32> {
- self.to_f64().and_then(|x| x.to_f32())
- }
-
- /// Converts the value of `self` to an `f64`.
- #[inline]
- fn to_f64(&self) -> Option<f64> {
- self.to_i64().and_then(|x| x.to_f64())
- }
-}
-
-macro_rules! impl_to_primitive_int_to_int(
- ($SrcT:ty, $DstT:ty) => (
- {
- if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) {
- Some(*self as $DstT)
- } else {
- let n = *self as i64;
- let min_value: $DstT = Bounded::min_value();
- let max_value: $DstT = Bounded::max_value();
- if min_value as i64 <= n && n <= max_value as i64 {
- Some(*self as $DstT)
- } else {
- None
- }
- }
- }
- )
-)
-
-macro_rules! impl_to_primitive_int_to_uint(
- ($SrcT:ty, $DstT:ty) => (
- {
- let zero: $SrcT = Zero::zero();
- let max_value: $DstT = Bounded::max_value();
- if zero <= *self && *self as u64 <= max_value as u64 {
- Some(*self as $DstT)
- } else {
- None
- }
- }
- )
-)
-
-macro_rules! impl_to_primitive_int(
- ($T:ty) => (
- impl ToPrimitive for $T {
- #[inline]
- fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int) }
- #[inline]
- fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8) }
- #[inline]
- fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16) }
- #[inline]
- fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32) }
- #[inline]
- fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64) }
-
- #[inline]
- fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint) }
- #[inline]
- fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8) }
- #[inline]
- fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16) }
- #[inline]
- fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32) }
- #[inline]
- fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64) }
-
- #[inline]
- fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
- #[inline]
- fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
- }
- )
-)
-
-impl_to_primitive_int!(int)
-impl_to_primitive_int!(i8)
-impl_to_primitive_int!(i16)
-impl_to_primitive_int!(i32)
-impl_to_primitive_int!(i64)
-
-macro_rules! impl_to_primitive_uint_to_int(
- ($DstT:ty) => (
- {
- let max_value: $DstT = Bounded::max_value();
- if *self as u64 <= max_value as u64 {
- Some(*self as $DstT)
- } else {
- None
- }
- }
- )
-)
-
-macro_rules! impl_to_primitive_uint_to_uint(
- ($SrcT:ty, $DstT:ty) => (
- {
- if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) {
- Some(*self as $DstT)
- } else {
- let zero: $SrcT = Zero::zero();
- let max_value: $DstT = Bounded::max_value();
- if zero <= *self && *self as u64 <= max_value as u64 {
- Some(*self as $DstT)
- } else {
- None
- }
- }
- }
- )
-)
-
-macro_rules! impl_to_primitive_uint(
- ($T:ty) => (
- impl ToPrimitive for $T {
- #[inline]
- fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int) }
- #[inline]
- fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8) }
- #[inline]
- fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16) }
- #[inline]
- fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32) }
- #[inline]
- fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64) }
-
- #[inline]
- fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint) }
- #[inline]
- fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8) }
- #[inline]
- fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16) }
- #[inline]
- fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32) }
- #[inline]
- fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64) }
-
- #[inline]
- fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
- #[inline]
- fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
- }
- )
-)
-
-impl_to_primitive_uint!(uint)
-impl_to_primitive_uint!(u8)
-impl_to_primitive_uint!(u16)
-impl_to_primitive_uint!(u32)
-impl_to_primitive_uint!(u64)
-
-macro_rules! impl_to_primitive_float_to_float(
- ($SrcT:ty, $DstT:ty) => (
- if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) {
- Some(*self as $DstT)
- } else {
- let n = *self as f64;
- let max_value: $SrcT = Bounded::max_value();
- if -max_value as f64 <= n && n <= max_value as f64 {
- Some(*self as $DstT)
- } else {
- None
- }
- }
- )
-)
-
-macro_rules! impl_to_primitive_float(
- ($T:ty) => (
- impl ToPrimitive for $T {
- #[inline]
- fn to_int(&self) -> Option<int> { Some(*self as int) }
- #[inline]
- fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
- #[inline]
- fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
- #[inline]
- fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
- #[inline]
- fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
-
- #[inline]
- fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
- #[inline]
- fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
- #[inline]
- fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
- #[inline]
- fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
- #[inline]
- fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
-
- #[inline]
- fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32) }
- #[inline]
- fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64) }
- }
- )
-)
-
-impl_to_primitive_float!(f32)
-impl_to_primitive_float!(f64)
-
-/// A generic trait for converting a number to a value.
-pub trait FromPrimitive {
- /// Convert an `int` to return an optional value of this type. If the
- /// value cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_int(n: int) -> Option<Self> {
- FromPrimitive::from_i64(n as i64)
- }
-
- /// Convert an `i8` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_i8(n: i8) -> Option<Self> {
- FromPrimitive::from_i64(n as i64)
- }
-
- /// Convert an `i16` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_i16(n: i16) -> Option<Self> {
- FromPrimitive::from_i64(n as i64)
- }
-
- /// Convert an `i32` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_i32(n: i32) -> Option<Self> {
- FromPrimitive::from_i64(n as i64)
- }
-
- /// Convert an `i64` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- fn from_i64(n: i64) -> Option<Self>;
-
- /// Convert an `uint` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_uint(n: uint) -> Option<Self> {
- FromPrimitive::from_u64(n as u64)
- }
-
- /// Convert an `u8` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_u8(n: u8) -> Option<Self> {
- FromPrimitive::from_u64(n as u64)
- }
-
- /// Convert an `u16` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_u16(n: u16) -> Option<Self> {
- FromPrimitive::from_u64(n as u64)
- }
-
- /// Convert an `u32` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_u32(n: u32) -> Option<Self> {
- FromPrimitive::from_u64(n as u64)
- }
-
- /// Convert an `u64` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- fn from_u64(n: u64) -> Option<Self>;
-
- /// Convert a `f32` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_f32(n: f32) -> Option<Self> {
- FromPrimitive::from_f64(n as f64)
- }
-
- /// Convert a `f64` to return an optional value of this type. If the
- /// type cannot be represented by this value, the `None` is returned.
- #[inline]
- fn from_f64(n: f64) -> Option<Self> {
- FromPrimitive::from_i64(n as i64)
- }
-}
-
-/// A utility function that just calls `FromPrimitive::from_int`.
-pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
- FromPrimitive::from_int(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i8`.
-pub fn from_i8<A: FromPrimitive>(n: i8) -> Option<A> {
- FromPrimitive::from_i8(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i16`.
-pub fn from_i16<A: FromPrimitive>(n: i16) -> Option<A> {
- FromPrimitive::from_i16(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i32`.
-pub fn from_i32<A: FromPrimitive>(n: i32) -> Option<A> {
- FromPrimitive::from_i32(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i64`.
-pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
- FromPrimitive::from_i64(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_uint`.
-pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
- FromPrimitive::from_uint(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u8`.
-pub fn from_u8<A: FromPrimitive>(n: u8) -> Option<A> {
- FromPrimitive::from_u8(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u16`.
-pub fn from_u16<A: FromPrimitive>(n: u16) -> Option<A> {
- FromPrimitive::from_u16(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u32`.
-pub fn from_u32<A: FromPrimitive>(n: u32) -> Option<A> {
- FromPrimitive::from_u32(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u64`.
-pub fn from_u64<A: FromPrimitive>(n: u64) -> Option<A> {
- FromPrimitive::from_u64(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_f32`.
-pub fn from_f32<A: FromPrimitive>(n: f32) -> Option<A> {
- FromPrimitive::from_f32(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_f64`.
-pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
- FromPrimitive::from_f64(n)
-}
-
-macro_rules! impl_from_primitive(
- ($T:ty, $to_ty:expr) => (
- impl FromPrimitive for $T {
- #[inline] fn from_int(n: int) -> Option<$T> { $to_ty }
- #[inline] fn from_i8(n: i8) -> Option<$T> { $to_ty }
- #[inline] fn from_i16(n: i16) -> Option<$T> { $to_ty }
- #[inline] fn from_i32(n: i32) -> Option<$T> { $to_ty }
- #[inline] fn from_i64(n: i64) -> Option<$T> { $to_ty }
-
- #[inline] fn from_uint(n: uint) -> Option<$T> { $to_ty }
- #[inline] fn from_u8(n: u8) -> Option<$T> { $to_ty }
- #[inline] fn from_u16(n: u16) -> Option<$T> { $to_ty }
- #[inline] fn from_u32(n: u32) -> Option<$T> { $to_ty }
- #[inline] fn from_u64(n: u64) -> Option<$T> { $to_ty }
-
- #[inline] fn from_f32(n: f32) -> Option<$T> { $to_ty }
- #[inline] fn from_f64(n: f64) -> Option<$T> { $to_ty }
- }
- )
-)
-
-impl_from_primitive!(int, n.to_int())
-impl_from_primitive!(i8, n.to_i8())
-impl_from_primitive!(i16, n.to_i16())
-impl_from_primitive!(i32, n.to_i32())
-impl_from_primitive!(i64, n.to_i64())
-impl_from_primitive!(uint, n.to_uint())
-impl_from_primitive!(u8, n.to_u8())
-impl_from_primitive!(u16, n.to_u16())
-impl_from_primitive!(u32, n.to_u32())
-impl_from_primitive!(u64, n.to_u64())
-impl_from_primitive!(f32, n.to_f32())
-impl_from_primitive!(f64, n.to_f64())
-
-/// Cast from one machine scalar to another.
-///
-/// # Example
-///
-/// ```
-/// let twenty: f32 = num::cast(0x14).unwrap();
-/// assert_eq!(twenty, 20f32);
-/// ```
-///
-#[inline]
-pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> {
- NumCast::from(n)
-}
-
-/// An interface for casting between machine scalars
-pub trait NumCast: ToPrimitive {
- fn from<T: ToPrimitive>(n: T) -> Option<Self>;
-}
-
-macro_rules! impl_num_cast(
- ($T:ty, $conv:ident) => (
- impl NumCast for $T {
- #[inline]
- fn from<N: ToPrimitive>(n: N) -> Option<$T> {
- // `$conv` could be generated using `concat_idents!`, but that
- // macro seems to be broken at the moment
- n.$conv()
- }
- }
- )
-)
-
-impl_num_cast!(u8, to_u8)
-impl_num_cast!(u16, to_u16)
-impl_num_cast!(u32, to_u32)
-impl_num_cast!(u64, to_u64)
-impl_num_cast!(uint, to_uint)
-impl_num_cast!(i8, to_i8)
-impl_num_cast!(i16, to_i16)
-impl_num_cast!(i32, to_i32)
-impl_num_cast!(i64, to_i64)
-impl_num_cast!(int, to_int)
-impl_num_cast!(f32, to_f32)
-impl_num_cast!(f64, to_f64)
-
-pub trait ToStrRadix {
- fn to_str_radix(&self, radix: uint) -> ~str;
-}
-
-pub trait FromStrRadix {
- fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
-}
-
-/// A utility function that just calls FromStrRadix::from_str_radix.
-pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
- FromStrRadix::from_str_radix(str, radix)
-}
-
-/// Calculates a power to a given radix, optimized for uint `pow` and `radix`.
-///
-/// Returns `radix^pow` as `T`.
-///
-/// Note:
-/// Also returns `1` for `0^0`, despite that technically being an
-/// undefined number. The reason for this is twofold:
-/// - If code written to use this function cares about that special case, it's
-/// probably going to catch it before making the call.
-/// - If code written to use this function doesn't care about it, it's
-/// probably assuming that `x^0` always equals `1`.
-///
-pub fn pow_with_uint<T:NumCast+One+Zero+Div<T,T>+Mul<T,T>>(radix: uint, pow: uint) -> T {
- let _0: T = Zero::zero();
- let _1: T = One::one();
-
- if pow == 0u { return _1; }
- if radix == 0u { return _0; }
- let mut my_pow = pow;
- let mut total = _1;
- let mut multiplier = cast(radix).unwrap();
- while (my_pow > 0u) {
- if my_pow % 2u == 1u {
- total = total * multiplier;
- }
- my_pow = my_pow / 2u;
- multiplier = multiplier * multiplier;
- }
- total
-}
-
-impl<T: Zero + 'static> Zero for @mut T {
- fn zero() -> @mut T { @mut Zero::zero() }
- fn is_zero(&self) -> bool { (**self).is_zero() }
-}
-
-impl<T: Zero + 'static> Zero for @T {
- fn zero() -> @T { @Zero::zero() }
- fn is_zero(&self) -> bool { (**self).is_zero() }
-}
-
-impl<T: Zero> Zero for ~T {
- fn zero() -> ~T { ~Zero::zero() }
- fn is_zero(&self) -> bool { (**self).is_zero() }
-}
-
-/// Saturating math operations
-pub trait Saturating {
- /// Saturating addition operator.
- /// Returns a+b, saturating at the numeric bounds instead of overflowing.
- fn saturating_add(self, v: Self) -> Self;
-
- /// Saturating subtraction operator.
- /// Returns a-b, saturating at the numeric bounds instead of overflowing.
- fn saturating_sub(self, v: Self) -> Self;
-}
-
-impl<T: CheckedAdd + CheckedSub + Zero + Ord + Bounded> Saturating for T {
- #[inline]
- fn saturating_add(self, v: T) -> T {
- match self.checked_add(&v) {
- Some(x) => x,
- None => if v >= Zero::zero() {
- Bounded::max_value()
- } else {
- Bounded::min_value()
- }
- }
- }
-
- #[inline]
- fn saturating_sub(self, v: T) -> T {
- match self.checked_sub(&v) {
- Some(x) => x,
- None => if v >= Zero::zero() {
- Bounded::min_value()
- } else {
- Bounded::max_value()
- }
- }
- }
-}
-
-pub trait CheckedAdd: Add<Self, Self> {
- fn checked_add(&self, v: &Self) -> Option<Self>;
-}
-
-pub trait CheckedSub: Sub<Self, Self> {
- fn checked_sub(&self, v: &Self) -> Option<Self>;
-}
-
-pub trait CheckedMul: Mul<Self, Self> {
- fn checked_mul(&self, v: &Self) -> Option<Self>;
-}
-
-pub trait CheckedDiv: Div<Self, Self> {
- fn checked_div(&self, v: &Self) -> Option<Self>;
-}
-
-/// Helper function for testing numeric operations
-#[cfg(test)]
-pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
- assert_eq!(ten.add(&two), cast(12).unwrap());
- assert_eq!(ten.sub(&two), cast(8).unwrap());
- assert_eq!(ten.mul(&two), cast(20).unwrap());
- assert_eq!(ten.div(&two), cast(5).unwrap());
- assert_eq!(ten.rem(&two), cast(0).unwrap());
-
- assert_eq!(ten.add(&two), ten + two);
- assert_eq!(ten.sub(&two), ten - two);
- assert_eq!(ten.mul(&two), ten * two);
- assert_eq!(ten.div(&two), ten / two);
- assert_eq!(ten.rem(&two), ten % two);
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use super::*;
- use i8;
- use i16;
- use i32;
- use i64;
- use int;
- use u8;
- use u16;
- use u32;
- use u64;
- use uint;
-
- macro_rules! test_cast_20(
- ($_20:expr) => ({
- let _20 = $_20;
-
- assert_eq!(20u, _20.to_uint().unwrap());
- assert_eq!(20u8, _20.to_u8().unwrap());
- assert_eq!(20u16, _20.to_u16().unwrap());
- assert_eq!(20u32, _20.to_u32().unwrap());
- assert_eq!(20u64, _20.to_u64().unwrap());
- assert_eq!(20i, _20.to_int().unwrap());
- assert_eq!(20i8, _20.to_i8().unwrap());
- assert_eq!(20i16, _20.to_i16().unwrap());
- assert_eq!(20i32, _20.to_i32().unwrap());
- assert_eq!(20i64, _20.to_i64().unwrap());
- assert_eq!(20f32, _20.to_f32().unwrap());
- assert_eq!(20f64, _20.to_f64().unwrap());
-
- assert_eq!(_20, NumCast::from(20u).unwrap());
- assert_eq!(_20, NumCast::from(20u8).unwrap());
- assert_eq!(_20, NumCast::from(20u16).unwrap());
- assert_eq!(_20, NumCast::from(20u32).unwrap());
- assert_eq!(_20, NumCast::from(20u64).unwrap());
- assert_eq!(_20, NumCast::from(20i).unwrap());
- assert_eq!(_20, NumCast::from(20i8).unwrap());
- assert_eq!(_20, NumCast::from(20i16).unwrap());
- assert_eq!(_20, NumCast::from(20i32).unwrap());
- assert_eq!(_20, NumCast::from(20i64).unwrap());
- assert_eq!(_20, NumCast::from(20f32).unwrap());
- assert_eq!(_20, NumCast::from(20f64).unwrap());
-
- assert_eq!(_20, cast(20u).unwrap());
- assert_eq!(_20, cast(20u8).unwrap());
- assert_eq!(_20, cast(20u16).unwrap());
- assert_eq!(_20, cast(20u32).unwrap());
- assert_eq!(_20, cast(20u64).unwrap());
- assert_eq!(_20, cast(20i).unwrap());
- assert_eq!(_20, cast(20i8).unwrap());
- assert_eq!(_20, cast(20i16).unwrap());
- assert_eq!(_20, cast(20i32).unwrap());
- assert_eq!(_20, cast(20i64).unwrap());
- assert_eq!(_20, cast(20f32).unwrap());
- assert_eq!(_20, cast(20f64).unwrap());
- })
- )
-
- #[test] fn test_u8_cast() { test_cast_20!(20u8) }
- #[test] fn test_u16_cast() { test_cast_20!(20u16) }
- #[test] fn test_u32_cast() { test_cast_20!(20u32) }
- #[test] fn test_u64_cast() { test_cast_20!(20u64) }
- #[test] fn test_uint_cast() { test_cast_20!(20u) }
- #[test] fn test_i8_cast() { test_cast_20!(20i8) }
- #[test] fn test_i16_cast() { test_cast_20!(20i16) }
- #[test] fn test_i32_cast() { test_cast_20!(20i32) }
- #[test] fn test_i64_cast() { test_cast_20!(20i64) }
- #[test] fn test_int_cast() { test_cast_20!(20i) }
- #[test] fn test_f32_cast() { test_cast_20!(20f32) }
- #[test] fn test_f64_cast() { test_cast_20!(20f64) }
-
- #[test]
- fn test_cast_range_int_min() {
- assert_eq!(int::min_value.to_int(), Some(int::min_value as int));
- assert_eq!(int::min_value.to_i8(), None);
- assert_eq!(int::min_value.to_i16(), None);
- // int::min_value.to_i32() is word-size specific
- assert_eq!(int::min_value.to_i64(), Some(int::min_value as i64));
- assert_eq!(int::min_value.to_uint(), None);
- assert_eq!(int::min_value.to_u8(), None);
- assert_eq!(int::min_value.to_u16(), None);
- assert_eq!(int::min_value.to_u32(), None);
- assert_eq!(int::min_value.to_u64(), None);
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(int::min_value.to_i32(), Some(int::min_value as i32));
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(int::min_value.to_i32(), None);
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_cast_range_i8_min() {
- assert_eq!(i8::min_value.to_int(), Some(i8::min_value as int));
- assert_eq!(i8::min_value.to_i8(), Some(i8::min_value as i8));
- assert_eq!(i8::min_value.to_i16(), Some(i8::min_value as i16));
- assert_eq!(i8::min_value.to_i32(), Some(i8::min_value as i32));
- assert_eq!(i8::min_value.to_i64(), Some(i8::min_value as i64));
- assert_eq!(i8::min_value.to_uint(), None);
- assert_eq!(i8::min_value.to_u8(), None);
- assert_eq!(i8::min_value.to_u16(), None);
- assert_eq!(i8::min_value.to_u32(), None);
- assert_eq!(i8::min_value.to_u64(), None);
- }
-
- #[test]
- fn test_cast_range_i16_min() {
- assert_eq!(i16::min_value.to_int(), Some(i16::min_value as int));
- assert_eq!(i16::min_value.to_i8(), None);
- assert_eq!(i16::min_value.to_i16(), Some(i16::min_value as i16));
- assert_eq!(i16::min_value.to_i32(), Some(i16::min_value as i32));
- assert_eq!(i16::min_value.to_i64(), Some(i16::min_value as i64));
- assert_eq!(i16::min_value.to_uint(), None);
- assert_eq!(i16::min_value.to_u8(), None);
- assert_eq!(i16::min_value.to_u16(), None);
- assert_eq!(i16::min_value.to_u32(), None);
- assert_eq!(i16::min_value.to_u64(), None);
- }
-
- #[test]
- fn test_cast_range_i32_min() {
- assert_eq!(i32::min_value.to_int(), Some(i32::min_value as int));
- assert_eq!(i32::min_value.to_i8(), None);
- assert_eq!(i32::min_value.to_i16(), None);
- assert_eq!(i32::min_value.to_i32(), Some(i32::min_value as i32));
- assert_eq!(i32::min_value.to_i64(), Some(i32::min_value as i64));
- assert_eq!(i32::min_value.to_uint(), None);
- assert_eq!(i32::min_value.to_u8(), None);
- assert_eq!(i32::min_value.to_u16(), None);
- assert_eq!(i32::min_value.to_u32(), None);
- assert_eq!(i32::min_value.to_u64(), None);
- }
-
- #[test]
- fn test_cast_range_i64_min() {
- // i64::min_value.to_int() is word-size specific
- assert_eq!(i64::min_value.to_i8(), None);
- assert_eq!(i64::min_value.to_i16(), None);
- assert_eq!(i64::min_value.to_i32(), None);
- assert_eq!(i64::min_value.to_i64(), Some(i64::min_value as i64));
- assert_eq!(i64::min_value.to_uint(), None);
- assert_eq!(i64::min_value.to_u8(), None);
- assert_eq!(i64::min_value.to_u16(), None);
- assert_eq!(i64::min_value.to_u32(), None);
- assert_eq!(i64::min_value.to_u64(), None);
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(i64::min_value.to_int(), None);
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(i64::min_value.to_int(), Some(i64::min_value as int));
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_cast_range_int_max() {
- assert_eq!(int::max_value.to_int(), Some(int::max_value as int));
- assert_eq!(int::max_value.to_i8(), None);
- assert_eq!(int::max_value.to_i16(), None);
- // int::max_value.to_i32() is word-size specific
- assert_eq!(int::max_value.to_i64(), Some(int::max_value as i64));
- assert_eq!(int::max_value.to_u8(), None);
- assert_eq!(int::max_value.to_u16(), None);
- // int::max_value.to_u32() is word-size specific
- assert_eq!(int::max_value.to_u64(), Some(int::max_value as u64));
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(int::max_value.to_i32(), Some(int::max_value as i32));
- assert_eq!(int::max_value.to_u32(), Some(int::max_value as u32));
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(int::max_value.to_i32(), None);
- assert_eq!(int::max_value.to_u32(), None);
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_cast_range_i8_max() {
- assert_eq!(i8::max_value.to_int(), Some(i8::max_value as int));
- assert_eq!(i8::max_value.to_i8(), Some(i8::max_value as i8));
- assert_eq!(i8::max_value.to_i16(), Some(i8::max_value as i16));
- assert_eq!(i8::max_value.to_i32(), Some(i8::max_value as i32));
- assert_eq!(i8::max_value.to_i64(), Some(i8::max_value as i64));
- assert_eq!(i8::max_value.to_uint(), Some(i8::max_value as uint));
- assert_eq!(i8::max_value.to_u8(), Some(i8::max_value as u8));
- assert_eq!(i8::max_value.to_u16(), Some(i8::max_value as u16));
- assert_eq!(i8::max_value.to_u32(), Some(i8::max_value as u32));
- assert_eq!(i8::max_value.to_u64(), Some(i8::max_value as u64));
- }
-
- #[test]
- fn test_cast_range_i16_max() {
- assert_eq!(i16::max_value.to_int(), Some(i16::max_value as int));
- assert_eq!(i16::max_value.to_i8(), None);
- assert_eq!(i16::max_value.to_i16(), Some(i16::max_value as i16));
- assert_eq!(i16::max_value.to_i32(), Some(i16::max_value as i32));
- assert_eq!(i16::max_value.to_i64(), Some(i16::max_value as i64));
- assert_eq!(i16::max_value.to_uint(), Some(i16::max_value as uint));
- assert_eq!(i16::max_value.to_u8(), None);
- assert_eq!(i16::max_value.to_u16(), Some(i16::max_value as u16));
- assert_eq!(i16::max_value.to_u32(), Some(i16::max_value as u32));
- assert_eq!(i16::max_value.to_u64(), Some(i16::max_value as u64));
- }
-
- #[test]
- fn test_cast_range_i32_max() {
- assert_eq!(i32::max_value.to_int(), Some(i32::max_value as int));
- assert_eq!(i32::max_value.to_i8(), None);
- assert_eq!(i32::max_value.to_i16(), None);
- assert_eq!(i32::max_value.to_i32(), Some(i32::max_value as i32));
- assert_eq!(i32::max_value.to_i64(), Some(i32::max_value as i64));
- assert_eq!(i32::max_value.to_uint(), Some(i32::max_value as uint));
- assert_eq!(i32::max_value.to_u8(), None);
- assert_eq!(i32::max_value.to_u16(), None);
- assert_eq!(i32::max_value.to_u32(), Some(i32::max_value as u32));
- assert_eq!(i32::max_value.to_u64(), Some(i32::max_value as u64));
- }
-
- #[test]
- fn test_cast_range_i64_max() {
- // i64::max_value.to_int() is word-size specific
- assert_eq!(i64::max_value.to_i8(), None);
- assert_eq!(i64::max_value.to_i16(), None);
- assert_eq!(i64::max_value.to_i32(), None);
- assert_eq!(i64::max_value.to_i64(), Some(i64::max_value as i64));
- // i64::max_value.to_uint() is word-size specific
- assert_eq!(i64::max_value.to_u8(), None);
- assert_eq!(i64::max_value.to_u16(), None);
- assert_eq!(i64::max_value.to_u32(), None);
- assert_eq!(i64::max_value.to_u64(), Some(i64::max_value as u64));
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(i64::max_value.to_int(), None);
- assert_eq!(i64::max_value.to_uint(), None);
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(i64::max_value.to_int(), Some(i64::max_value as int));
- assert_eq!(i64::max_value.to_uint(), Some(i64::max_value as uint));
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_cast_range_uint_min() {
- assert_eq!(uint::min_value.to_int(), Some(uint::min_value as int));
- assert_eq!(uint::min_value.to_i8(), Some(uint::min_value as i8));
- assert_eq!(uint::min_value.to_i16(), Some(uint::min_value as i16));
- assert_eq!(uint::min_value.to_i32(), Some(uint::min_value as i32));
- assert_eq!(uint::min_value.to_i64(), Some(uint::min_value as i64));
- assert_eq!(uint::min_value.to_uint(), Some(uint::min_value as uint));
- assert_eq!(uint::min_value.to_u8(), Some(uint::min_value as u8));
- assert_eq!(uint::min_value.to_u16(), Some(uint::min_value as u16));
- assert_eq!(uint::min_value.to_u32(), Some(uint::min_value as u32));
- assert_eq!(uint::min_value.to_u64(), Some(uint::min_value as u64));
- }
-
- #[test]
- fn test_cast_range_u8_min() {
- assert_eq!(u8::min_value.to_int(), Some(u8::min_value as int));
- assert_eq!(u8::min_value.to_i8(), Some(u8::min_value as i8));
- assert_eq!(u8::min_value.to_i16(), Some(u8::min_value as i16));
- assert_eq!(u8::min_value.to_i32(), Some(u8::min_value as i32));
- assert_eq!(u8::min_value.to_i64(), Some(u8::min_value as i64));
- assert_eq!(u8::min_value.to_uint(), Some(u8::min_value as uint));
- assert_eq!(u8::min_value.to_u8(), Some(u8::min_value as u8));
- assert_eq!(u8::min_value.to_u16(), Some(u8::min_value as u16));
- assert_eq!(u8::min_value.to_u32(), Some(u8::min_value as u32));
- assert_eq!(u8::min_value.to_u64(), Some(u8::min_value as u64));
- }
-
- #[test]
- fn test_cast_range_u16_min() {
- assert_eq!(u16::min_value.to_int(), Some(u16::min_value as int));
- assert_eq!(u16::min_value.to_i8(), Some(u16::min_value as i8));
- assert_eq!(u16::min_value.to_i16(), Some(u16::min_value as i16));
- assert_eq!(u16::min_value.to_i32(), Some(u16::min_value as i32));
- assert_eq!(u16::min_value.to_i64(), Some(u16::min_value as i64));
- assert_eq!(u16::min_value.to_uint(), Some(u16::min_value as uint));
- assert_eq!(u16::min_value.to_u8(), Some(u16::min_value as u8));
- assert_eq!(u16::min_value.to_u16(), Some(u16::min_value as u16));
- assert_eq!(u16::min_value.to_u32(), Some(u16::min_value as u32));
- assert_eq!(u16::min_value.to_u64(), Some(u16::min_value as u64));
- }
-
- #[test]
- fn test_cast_range_u32_min() {
- assert_eq!(u32::min_value.to_int(), Some(u32::min_value as int));
- assert_eq!(u32::min_value.to_i8(), Some(u32::min_value as i8));
- assert_eq!(u32::min_value.to_i16(), Some(u32::min_value as i16));
- assert_eq!(u32::min_value.to_i32(), Some(u32::min_value as i32));
- assert_eq!(u32::min_value.to_i64(), Some(u32::min_value as i64));
- assert_eq!(u32::min_value.to_uint(), Some(u32::min_value as uint));
- assert_eq!(u32::min_value.to_u8(), Some(u32::min_value as u8));
- assert_eq!(u32::min_value.to_u16(), Some(u32::min_value as u16));
- assert_eq!(u32::min_value.to_u32(), Some(u32::min_value as u32));
- assert_eq!(u32::min_value.to_u64(), Some(u32::min_value as u64));
- }
-
- #[test]
- fn test_cast_range_u64_min() {
- assert_eq!(u64::min_value.to_int(), Some(u64::min_value as int));
- assert_eq!(u64::min_value.to_i8(), Some(u64::min_value as i8));
- assert_eq!(u64::min_value.to_i16(), Some(u64::min_value as i16));
- assert_eq!(u64::min_value.to_i32(), Some(u64::min_value as i32));
- assert_eq!(u64::min_value.to_i64(), Some(u64::min_value as i64));
- assert_eq!(u64::min_value.to_uint(), Some(u64::min_value as uint));
- assert_eq!(u64::min_value.to_u8(), Some(u64::min_value as u8));
- assert_eq!(u64::min_value.to_u16(), Some(u64::min_value as u16));
- assert_eq!(u64::min_value.to_u32(), Some(u64::min_value as u32));
- assert_eq!(u64::min_value.to_u64(), Some(u64::min_value as u64));
- }
-
- #[test]
- fn test_cast_range_uint_max() {
- assert_eq!(uint::max_value.to_int(), None);
- assert_eq!(uint::max_value.to_i8(), None);
- assert_eq!(uint::max_value.to_i16(), None);
- assert_eq!(uint::max_value.to_i32(), None);
- // uint::max_value.to_i64() is word-size specific
- assert_eq!(uint::max_value.to_u8(), None);
- assert_eq!(uint::max_value.to_u16(), None);
- // uint::max_value.to_u32() is word-size specific
- assert_eq!(uint::max_value.to_u64(), Some(uint::max_value as u64));
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(uint::max_value.to_u32(), Some(uint::max_value as u32));
- assert_eq!(uint::max_value.to_i64(), Some(uint::max_value as i64));
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(uint::max_value.to_u32(), None);
- assert_eq!(uint::max_value.to_i64(), None);
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_cast_range_u8_max() {
- assert_eq!(u8::max_value.to_int(), Some(u8::max_value as int));
- assert_eq!(u8::max_value.to_i8(), None);
- assert_eq!(u8::max_value.to_i16(), Some(u8::max_value as i16));
- assert_eq!(u8::max_value.to_i32(), Some(u8::max_value as i32));
- assert_eq!(u8::max_value.to_i64(), Some(u8::max_value as i64));
- assert_eq!(u8::max_value.to_uint(), Some(u8::max_value as uint));
- assert_eq!(u8::max_value.to_u8(), Some(u8::max_value as u8));
- assert_eq!(u8::max_value.to_u16(), Some(u8::max_value as u16));
- assert_eq!(u8::max_value.to_u32(), Some(u8::max_value as u32));
- assert_eq!(u8::max_value.to_u64(), Some(u8::max_value as u64));
- }
-
- #[test]
- fn test_cast_range_u16_max() {
- assert_eq!(u16::max_value.to_int(), Some(u16::max_value as int));
- assert_eq!(u16::max_value.to_i8(), None);
- assert_eq!(u16::max_value.to_i16(), None);
- assert_eq!(u16::max_value.to_i32(), Some(u16::max_value as i32));
- assert_eq!(u16::max_value.to_i64(), Some(u16::max_value as i64));
- assert_eq!(u16::max_value.to_uint(), Some(u16::max_value as uint));
- assert_eq!(u16::max_value.to_u8(), None);
- assert_eq!(u16::max_value.to_u16(), Some(u16::max_value as u16));
- assert_eq!(u16::max_value.to_u32(), Some(u16::max_value as u32));
- assert_eq!(u16::max_value.to_u64(), Some(u16::max_value as u64));
- }
-
- #[test]
- fn test_cast_range_u32_max() {
- // u32::max_value.to_int() is word-size specific
- assert_eq!(u32::max_value.to_i8(), None);
- assert_eq!(u32::max_value.to_i16(), None);
- assert_eq!(u32::max_value.to_i32(), None);
- assert_eq!(u32::max_value.to_i64(), Some(u32::max_value as i64));
- assert_eq!(u32::max_value.to_uint(), Some(u32::max_value as uint));
- assert_eq!(u32::max_value.to_u8(), None);
- assert_eq!(u32::max_value.to_u16(), None);
- assert_eq!(u32::max_value.to_u32(), Some(u32::max_value as u32));
- assert_eq!(u32::max_value.to_u64(), Some(u32::max_value as u64));
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(u32::max_value.to_int(), None);
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(u32::max_value.to_int(), Some(u32::max_value as int));
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_cast_range_u64_max() {
- assert_eq!(u64::max_value.to_int(), None);
- assert_eq!(u64::max_value.to_i8(), None);
- assert_eq!(u64::max_value.to_i16(), None);
- assert_eq!(u64::max_value.to_i32(), None);
- assert_eq!(u64::max_value.to_i64(), None);
- // u64::max_value.to_uint() is word-size specific
- assert_eq!(u64::max_value.to_u8(), None);
- assert_eq!(u64::max_value.to_u16(), None);
- assert_eq!(u64::max_value.to_u32(), None);
- assert_eq!(u64::max_value.to_u64(), Some(u64::max_value as u64));
-
- #[cfg(target_word_size = "32")]
- fn check_word_size() {
- assert_eq!(u64::max_value.to_uint(), None);
- }
-
- #[cfg(target_word_size = "64")]
- fn check_word_size() {
- assert_eq!(u64::max_value.to_uint(), Some(u64::max_value as uint));
- }
-
- check_word_size();
- }
-
- #[test]
- fn test_saturating_add_uint() {
- use uint::max_value;
- assert_eq!(3u.saturating_add(5u), 8u);
- assert_eq!(3u.saturating_add(max_value-1), max_value);
- assert_eq!(max_value.saturating_add(max_value), max_value);
- assert_eq!((max_value-2).saturating_add(1), max_value-1);
- }
-
- #[test]
- fn test_saturating_sub_uint() {
- use uint::max_value;
- assert_eq!(5u.saturating_sub(3u), 2u);
- assert_eq!(3u.saturating_sub(5u), 0u);
- assert_eq!(0u.saturating_sub(1u), 0u);
- assert_eq!((max_value-1).saturating_sub(max_value), 0);
- }
-
- #[test]
- fn test_saturating_add_int() {
- use int::{min_value,max_value};
- assert_eq!(3i.saturating_add(5i), 8i);
- assert_eq!(3i.saturating_add(max_value-1), max_value);
- assert_eq!(max_value.saturating_add(max_value), max_value);
- assert_eq!((max_value-2).saturating_add(1), max_value-1);
- assert_eq!(3i.saturating_add(-5i), -2i);
- assert_eq!(min_value.saturating_add(-1i), min_value);
- assert_eq!((-2i).saturating_add(-max_value), min_value);
- }
-
- #[test]
- fn test_saturating_sub_int() {
- use int::{min_value,max_value};
- assert_eq!(3i.saturating_sub(5i), -2i);
- assert_eq!(min_value.saturating_sub(1i), min_value);
- assert_eq!((-2i).saturating_sub(max_value), min_value);
- assert_eq!(3i.saturating_sub(-5i), 8i);
- assert_eq!(3i.saturating_sub(-(max_value-1)), max_value);
- assert_eq!(max_value.saturating_sub(-max_value), max_value);
- assert_eq!((max_value-2).saturating_sub(-1), max_value-1);
- }
-
- #[test]
- fn test_checked_add() {
- let five_less = uint::max_value - 5;
- assert_eq!(five_less.checked_add(&0), Some(uint::max_value - 5));
- assert_eq!(five_less.checked_add(&1), Some(uint::max_value - 4));
- assert_eq!(five_less.checked_add(&2), Some(uint::max_value - 3));
- assert_eq!(five_less.checked_add(&3), Some(uint::max_value - 2));
- assert_eq!(five_less.checked_add(&4), Some(uint::max_value - 1));
- assert_eq!(five_less.checked_add(&5), Some(uint::max_value));
- assert_eq!(five_less.checked_add(&6), None);
- assert_eq!(five_less.checked_add(&7), None);
- }
-
- #[test]
- fn test_checked_sub() {
- assert_eq!(5u.checked_sub(&0), Some(5));
- assert_eq!(5u.checked_sub(&1), Some(4));
- assert_eq!(5u.checked_sub(&2), Some(3));
- assert_eq!(5u.checked_sub(&3), Some(2));
- assert_eq!(5u.checked_sub(&4), Some(1));
- assert_eq!(5u.checked_sub(&5), Some(0));
- assert_eq!(5u.checked_sub(&6), None);
- assert_eq!(5u.checked_sub(&7), None);
- }
-
- #[test]
- fn test_checked_mul() {
- let third = uint::max_value / 3;
- assert_eq!(third.checked_mul(&0), Some(0));
- assert_eq!(third.checked_mul(&1), Some(third));
- assert_eq!(third.checked_mul(&2), Some(third * 2));
- assert_eq!(third.checked_mul(&3), Some(third * 3));
- assert_eq!(third.checked_mul(&4), None);
- }
-
-
- #[deriving(Eq)]
- struct Value { x: int }
-
- impl ToPrimitive for Value {
- fn to_i64(&self) -> Option<i64> { self.x.to_i64() }
- fn to_u64(&self) -> Option<u64> { self.x.to_u64() }
- }
-
- impl FromPrimitive for Value {
- fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as int }) }
- fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as int }) }
- }
-
- #[test]
- fn test_to_primitive() {
- let value = Value { x: 5 };
- assert_eq!(value.to_int(), Some(5));
- assert_eq!(value.to_i8(), Some(5));
- assert_eq!(value.to_i16(), Some(5));
- assert_eq!(value.to_i32(), Some(5));
- assert_eq!(value.to_i64(), Some(5));
- assert_eq!(value.to_uint(), Some(5));
- assert_eq!(value.to_u8(), Some(5));
- assert_eq!(value.to_u16(), Some(5));
- assert_eq!(value.to_u32(), Some(5));
- assert_eq!(value.to_u64(), Some(5));
- assert_eq!(value.to_f32(), Some(5f32));
- assert_eq!(value.to_f64(), Some(5f64));
- }
-
- #[test]
- fn test_from_primitive() {
- assert_eq!(from_int(5), Some(Value { x: 5 }));
- assert_eq!(from_i8(5), Some(Value { x: 5 }));
- assert_eq!(from_i16(5), Some(Value { x: 5 }));
- assert_eq!(from_i32(5), Some(Value { x: 5 }));
- assert_eq!(from_i64(5), Some(Value { x: 5 }));
- assert_eq!(from_uint(5), Some(Value { x: 5 }));
- assert_eq!(from_u8(5), Some(Value { x: 5 }));
- assert_eq!(from_u16(5), Some(Value { x: 5 }));
- assert_eq!(from_u32(5), Some(Value { x: 5 }));
- assert_eq!(from_u64(5), Some(Value { x: 5 }));
- assert_eq!(from_f32(5f32), Some(Value { x: 5 }));
- assert_eq!(from_f64(5f64), Some(Value { x: 5 }));
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[allow(missing_doc)];
-
-use clone::Clone;
-use container::Container;
-use std::cmp::{Ord, Eq};
-use ops::{Add, Sub, Mul, Div, Rem, Neg};
-use option::{None, Option, Some};
-use char;
-use str::{StrSlice};
-use str;
-use vec::{CopyableVector, ImmutableVector, MutableVector};
-use vec::OwnedVector;
-use num::{NumCast, Zero, One, cast, pow_with_uint, Integer};
-use num::{Round, Float, FPNaN, FPInfinite};
-
-pub enum ExponentFormat {
- ExpNone,
- ExpDec,
- ExpBin
-}
-
-pub enum SignificantDigits {
- DigAll,
- DigMax(uint),
- DigExact(uint)
-}
-
-pub enum SignFormat {
- SignNone,
- SignNeg,
- SignAll
-}
-
-pub trait NumStrConv {
- fn nan() -> Option<Self>;
- fn inf() -> Option<Self>;
- fn neg_inf() -> Option<Self>;
- fn neg_zero() -> Option<Self>;
-
- fn round_to_zero(&self) -> Self;
- fn fractional_part(&self) -> Self;
-}
-
-macro_rules! impl_NumStrConv_Floating (($t:ty) => (
- impl NumStrConv for $t {
- #[inline]
- fn nan() -> Option<$t> { Some( 0.0 / 0.0) }
- #[inline]
- fn inf() -> Option<$t> { Some( 1.0 / 0.0) }
- #[inline]
- fn neg_inf() -> Option<$t> { Some(-1.0 / 0.0) }
- #[inline]
- fn neg_zero() -> Option<$t> { Some(-0.0 ) }
-
- #[inline]
- fn round_to_zero(&self) -> $t { self.trunc() }
- #[inline]
- fn fractional_part(&self) -> $t { self.fract() }
- }
-))
-
-macro_rules! impl_NumStrConv_Integer (($t:ty) => (
- impl NumStrConv for $t {
- #[inline] fn nan() -> Option<$t> { None }
- #[inline] fn inf() -> Option<$t> { None }
- #[inline] fn neg_inf() -> Option<$t> { None }
- #[inline] fn neg_zero() -> Option<$t> { None }
-
- #[inline] fn round_to_zero(&self) -> $t { *self }
- #[inline] fn fractional_part(&self) -> $t { 0 }
- }
-))
-
-// FIXME: #4955
-// Replace by two generic impls for traits 'Integral' and 'Floating'
-impl_NumStrConv_Floating!(f32)
-impl_NumStrConv_Floating!(f64)
-
-impl_NumStrConv_Integer!(int)
-impl_NumStrConv_Integer!(i8)
-impl_NumStrConv_Integer!(i16)
-impl_NumStrConv_Integer!(i32)
-impl_NumStrConv_Integer!(i64)
-
-impl_NumStrConv_Integer!(uint)
-impl_NumStrConv_Integer!(u8)
-impl_NumStrConv_Integer!(u16)
-impl_NumStrConv_Integer!(u32)
-impl_NumStrConv_Integer!(u64)
-
-
-// Special value strings as [u8] consts.
-static INF_BUF: [u8, ..3] = ['i' as u8, 'n' as u8, 'f' as u8];
-static POS_INF_BUF: [u8, ..4] = ['+' as u8, 'i' as u8, 'n' as u8,
- 'f' as u8];
-static NEG_INF_BUF: [u8, ..4] = ['-' as u8, 'i' as u8, 'n' as u8,
- 'f' as u8];
-static NAN_BUF: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8];
-
-/**
- * Converts an integral number to its string representation as a byte vector.
- * This is meant to be a common base implementation for all integral string
- * conversion functions like `to_str()` or `to_str_radix()`.
- *
- * # Arguments
- * - `num` - The number to convert. Accepts any number that
- * implements the numeric traits.
- * - `radix` - Base to use. Accepts only the values 2-36.
- * - `sign` - How to emit the sign. Options are:
- * - `SignNone`: No sign at all. Basically emits `abs(num)`.
- * - `SignNeg`: Only `-` on negative values.
- * - `SignAll`: Both `+` on positive, and `-` on negative numbers.
- * - `f` - a callback which will be invoked for each ascii character
- * which composes the string representation of this integer
- *
- * # Return value
- * A tuple containing the byte vector, and a boolean flag indicating
- * whether it represents a special value like `inf`, `-inf`, `NaN` or not.
- * It returns a tuple because there can be ambiguity between a special value
- * and a number representation at higher bases.
- *
- * # Failure
- * - Fails if `radix` < 2 or `radix` > 36.
- */
-pub fn int_to_str_bytes_common<T:NumCast
- +Zero
- +Eq
- +Ord
- +Integer
- +Div<T,T>
- +Neg<T>
- +Rem<T,T>
- +Mul<T,T>>(
- num: T,
- radix: uint,
- sign: SignFormat,
- f: |u8|) {
- assert!(2 <= radix && radix <= 36);
-
- let _0: T = Zero::zero();
-
- let neg = num < _0;
- let radix_gen: T = cast(radix).unwrap();
-
- let mut deccum = num;
- // This is just for integral types, the largest of which is a u64. The
- // smallest base that we can have is 2, so the most number of digits we're
- // ever going to have is 64
- let mut buf = [0u8, ..64];
- let mut cur = 0;
-
- // Loop at least once to make sure at least a `0` gets emitted.
- loop {
- // Calculate the absolute value of each digit instead of only
- // doing it once for the whole number because a
- // representable negative number doesn't necessary have an
- // representable additive inverse of the same type
- // (See twos complement). But we assume that for the
- // numbers [-35 .. 0] we always have [0 .. 35].
- let current_digit_signed = deccum % radix_gen;
- let current_digit = if current_digit_signed < _0 {
- -current_digit_signed
- } else {
- current_digit_signed
- };
- buf[cur] = match current_digit.to_u8().unwrap() {
- i @ 0..9 => '0' as u8 + i,
- i => 'a' as u8 + (i - 10),
- };
- cur += 1;
-
- deccum = deccum / radix_gen;
- // No more digits to calculate for the non-fractional part -> break
- if deccum == _0 { break; }
- }
-
- // Decide what sign to put in front
- match sign {
- SignNeg | SignAll if neg => { f('-' as u8); }
- SignAll => { f('+' as u8); }
- _ => ()
- }
-
- // We built the number in reverse order, so un-reverse it here
- while cur > 0 {
- cur -= 1;
- f(buf[cur]);
- }
-}
-
-/**
- * Converts a number to its string representation as a byte vector.
- * This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
- *
- * # Arguments
- * - `num` - The number to convert. Accepts any number that
- * implements the numeric traits.
- * - `radix` - Base to use. Accepts only the values 2-36.
- * - `negative_zero` - Whether to treat the special value `-0` as
- * `-0` or as `+0`.
- * - `sign` - How to emit the sign. Options are:
- * - `SignNone`: No sign at all. Basically emits `abs(num)`.
- * - `SignNeg`: Only `-` on negative values.
- * - `SignAll`: Both `+` on positive, and `-` on negative numbers.
- * - `digits` - The amount of digits to use for emitting the
- * fractional part, if any. Options are:
- * - `DigAll`: All calculatable digits. Beware of bignums or
- * fractions!
- * - `DigMax(uint)`: Maximum N digits, truncating any trailing zeros.
- * - `DigExact(uint)`: Exactly N digits.
- *
- * # Return value
- * A tuple containing the byte vector, and a boolean flag indicating
- * whether it represents a special value like `inf`, `-inf`, `NaN` or not.
- * It returns a tuple because there can be ambiguity between a special value
- * and a number representation at higher bases.
- *
- * # Failure
- * - Fails if `radix` < 2 or `radix` > 36.
- */
-pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
- Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
- num: T, radix: uint, negative_zero: bool,
- sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) {
- assert!(2 <= radix && radix <= 36);
-
- let _0: T = Zero::zero();
- let _1: T = One::one();
-
- match num.classify() {
- FPNaN => { return ("NaN".as_bytes().to_owned(), true); }
- FPInfinite if num > _0 => {
- return match sign {
- SignAll => ("+inf".as_bytes().to_owned(), true),
- _ => ("inf".as_bytes().to_owned(), true)
- };
- }
- FPInfinite if num < _0 => {
- return match sign {
- SignNone => ("inf".as_bytes().to_owned(), true),
- _ => ("-inf".as_bytes().to_owned(), true),
- };
- }
- _ => {}
- }
-
- let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity());
- let mut buf: ~[u8] = ~[];
- let radix_gen: T = cast(radix as int).unwrap();
-
- // First emit the non-fractional part, looping at least once to make
- // sure at least a `0` gets emitted.
- let mut deccum = num.trunc();
- loop {
- // Calculate the absolute value of each digit instead of only
- // doing it once for the whole number because a
- // representable negative number doesn't necessary have an
- // representable additive inverse of the same type
- // (See twos complement). But we assume that for the
- // numbers [-35 .. 0] we always have [0 .. 35].
- let current_digit = (deccum % radix_gen).abs();
-
- // Decrease the deccumulator one digit at a time
- deccum = deccum / radix_gen;
- deccum = deccum.trunc();
-
- buf.push(char::from_digit(current_digit.to_int().unwrap() as uint, radix)
- .unwrap() as u8);
-
- // No more digits to calculate for the non-fractional part -> break
- if deccum == _0 { break; }
- }
-
- // If limited digits, calculate one digit more for rounding.
- let (limit_digits, digit_count, exact) = match digits {
- DigAll => (false, 0u, false),
- DigMax(count) => (true, count+1, false),
- DigExact(count) => (true, count+1, true)
- };
-
- // Decide what sign to put in front
- match sign {
- SignNeg | SignAll if neg => {
- buf.push('-' as u8);
- }
- SignAll => {
- buf.push('+' as u8);
- }
- _ => ()
- }
-
- buf.reverse();
-
- // Remember start of the fractional digits.
- // Points one beyond end of buf if none get generated,
- // or at the '.' otherwise.
- let start_fractional_digits = buf.len();
-
- // Now emit the fractional part, if any
- deccum = num.fract();
- if deccum != _0 || (limit_digits && exact && digit_count > 0) {
- buf.push('.' as u8);
- let mut dig = 0u;
-
- // calculate new digits while
- // - there is no limit and there are digits left
- // - or there is a limit, it's not reached yet and
- // - it's exact
- // - or it's a maximum, and there are still digits left
- while (!limit_digits && deccum != _0)
- || (limit_digits && dig < digit_count && (
- exact
- || (!exact && deccum != _0)
- )
- ) {
- // Shift first fractional digit into the integer part
- deccum = deccum * radix_gen;
-
- // Calculate the absolute value of each digit.
- // See note in first loop.
- let current_digit = deccum.trunc().abs();
-
- buf.push(char::from_digit(
- current_digit.to_int().unwrap() as uint, radix).unwrap() as u8);
-
- // Decrease the deccumulator one fractional digit at a time
- deccum = deccum.fract();
- dig += 1u;
- }
-
- // If digits are limited, and that limit has been reached,
- // cut off the one extra digit, and depending on its value
- // round the remaining ones.
- if limit_digits && dig == digit_count {
- let ascii2value = |chr: u8| {
- char::to_digit(chr as char, radix).unwrap() as uint
- };
- let value2ascii = |val: uint| {
- char::from_digit(val, radix).unwrap() as u8
- };
-
- let extra_digit = ascii2value(buf.pop());
- if extra_digit >= radix / 2 { // -> need to round
- let mut i: int = buf.len() as int - 1;
- loop {
- // If reached left end of number, have to
- // insert additional digit:
- if i < 0
- || buf[i] == '-' as u8
- || buf[i] == '+' as u8 {
- buf.insert((i + 1) as uint, value2ascii(1));
- break;
- }
-
- // Skip the '.'
- if buf[i] == '.' as u8 { i -= 1; continue; }
-
- // Either increment the digit,
- // or set to 0 if max and carry the 1.
- let current_digit = ascii2value(buf[i]);
- if current_digit < (radix - 1) {
- buf[i] = value2ascii(current_digit+1);
- break;
- } else {
- buf[i] = value2ascii(0);
- i -= 1;
- }
- }
- }
- }
- }
-
- // if number of digits is not exact, remove all trailing '0's up to
- // and including the '.'
- if !exact {
- let buf_max_i = buf.len() - 1;
-
- // index to truncate from
- let mut i = buf_max_i;
-
- // discover trailing zeros of fractional part
- while i > start_fractional_digits && buf[i] == '0' as u8 {
- i -= 1;
- }
-
- // Only attempt to truncate digits if buf has fractional digits
- if i >= start_fractional_digits {
- // If buf ends with '.', cut that too.
- if buf[i] == '.' as u8 { i -= 1 }
-
- // only resize buf if we actually remove digits
- if i < buf_max_i {
- buf = buf.slice(0, i + 1).to_owned();
- }
- }
- } // If exact and trailing '.', just cut that
- else {
- let max_i = buf.len() - 1;
- if buf[max_i] == '.' as u8 {
- buf = buf.slice(0, max_i).to_owned();
- }
- }
-
- (buf, false)
-}
-
-/**
- * Converts a number to its string representation. This is a wrapper for
- * `to_str_bytes_common()`, for details see there.
- */
-#[inline]
-pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+Round+
- Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
- num: T, radix: uint, negative_zero: bool,
- sign: SignFormat, digits: SignificantDigits) -> (~str, bool) {
- let (bytes, special) = float_to_str_bytes_common(num, radix,
- negative_zero, sign, digits);
- (str::from_utf8(bytes), special)
-}
-
-// Some constants for from_str_bytes_common's input validation,
-// they define minimum radix values for which the character is a valid digit.
-static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
-static DIGIT_I_RADIX: uint = ('i' as uint) - ('a' as uint) + 11u;
-static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
-
-/**
- * Parses a byte slice as a number. This is meant to
- * be a common base implementation for all numeric string conversion
- * functions like `from_str()` or `from_str_radix()`.
- *
- * # Arguments
- * - `buf` - The byte slice to parse.
- * - `radix` - Which base to parse the number as. Accepts 2-36.
- * - `negative` - Whether to accept negative numbers.
- * - `fractional` - Whether to accept numbers with fractional parts.
- * - `special` - Whether to accept special values like `inf`
- * and `NaN`. Can conflict with `radix`, see Failure.
- * - `exponent` - Which exponent format to accept. Options are:
- * - `ExpNone`: No Exponent, accepts just plain numbers like `42` or
- * `-8.2`.
- * - `ExpDec`: Accepts numbers with a decimal exponent like `42e5` or
- * `8.2E-2`. The exponent string itself is always base 10.
- * Can conflict with `radix`, see Failure.
- * - `ExpBin`: Accepts numbers with a binary exponent like `42P-8` or
- * `FFp128`. The exponent string itself is always base 10.
- * Can conflict with `radix`, see Failure.
- * - `empty_zero` - Whether to accept a empty `buf` as a 0 or not.
- * - `ignore_underscores` - Whether all underscores within the string should
- * be ignored.
- *
- * # Return value
- * Returns `Some(n)` if `buf` parses to a number n without overflowing, and
- * `None` otherwise, depending on the constraints set by the remaining
- * arguments.
- *
- * # Failure
- * - Fails if `radix` < 2 or `radix` > 36.
- * - Fails if `radix` > 14 and `exponent` is `ExpDec` due to conflict
- * between digit and exponent sign `'e'`.
- * - Fails if `radix` > 25 and `exponent` is `ExpBin` due to conflict
- * between digit and exponent sign `'p'`.
- * - Fails if `radix` > 18 and `special == true` due to conflict
- * between digit and lowest first character in `inf` and `NaN`, the `'i'`.
- */
-pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
- Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>+
- NumStrConv+Clone>(
- buf: &[u8], radix: uint, negative: bool, fractional: bool,
- special: bool, exponent: ExponentFormat, empty_zero: bool,
- ignore_underscores: bool
- ) -> Option<T> {
- match exponent {
- ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e'
- => fail!("from_str_bytes_common: radix {:?} incompatible with \
- use of 'e' as decimal exponent", radix),
- ExpBin if radix >= DIGIT_P_RADIX // binary exponent 'p'
- => fail!("from_str_bytes_common: radix {:?} incompatible with \
- use of 'p' as binary exponent", radix),
- _ if special && radix >= DIGIT_I_RADIX // first digit of 'inf'
- => fail!("from_str_bytes_common: radix {:?} incompatible with \
- special values 'inf' and 'NaN'", radix),
- _ if (radix as int) < 2
- => fail!("from_str_bytes_common: radix {:?} to low, \
- must lie in the range [2, 36]", radix),
- _ if (radix as int) > 36
- => fail!("from_str_bytes_common: radix {:?} to high, \
- must lie in the range [2, 36]", radix),
- _ => ()
- }
-
- let _0: T = Zero::zero();
- let _1: T = One::one();
- let radix_gen: T = cast(radix as int).unwrap();
-
- let len = buf.len();
-
- if len == 0 {
- if empty_zero {
- return Some(_0);
- } else {
- return None;
- }
- }
-
- if special {
- if buf == INF_BUF || buf == POS_INF_BUF {
- return NumStrConv::inf();
- } else if buf == NEG_INF_BUF {
- if negative {
- return NumStrConv::neg_inf();
- } else {
- return None;
- }
- } else if buf == NAN_BUF {
- return NumStrConv::nan();
- }
- }
-
- let (start, accum_positive) = match buf[0] as char {
- '-' if !negative => return None,
- '-' => (1u, false),
- '+' => (1u, true),
- _ => (0u, true)
- };
-
- // Initialize accumulator with signed zero for floating point parsing to
- // work
- let mut accum = if accum_positive { _0.clone() } else { -_1 * _0};
- let mut last_accum = accum.clone(); // Necessary to detect overflow
- let mut i = start;
- let mut exp_found = false;
-
- // Parse integer part of number
- while i < len {
- let c = buf[i] as char;
-
- match char::to_digit(c, radix) {
- Some(digit) => {
- // shift accum one digit left
- accum = accum * radix_gen.clone();
-
- // add/subtract current digit depending on sign
- if accum_positive {
- accum = accum + cast(digit as int).unwrap();
- } else {
- accum = accum - cast(digit as int).unwrap();
- }
-
- // Detect overflow by comparing to last value, except
- // if we've not seen any non-zero digits.
- if last_accum != _0 {
- if accum_positive && accum <= last_accum { return NumStrConv::inf(); }
- if !accum_positive && accum >= last_accum { return NumStrConv::neg_inf(); }
-
- // Detect overflow by reversing the shift-and-add proccess
- if accum_positive &&
- (last_accum != ((accum - cast(digit as int).unwrap())/radix_gen.clone())) {
- return NumStrConv::inf();
- }
- if !accum_positive &&
- (last_accum != ((accum + cast(digit as int).unwrap())/radix_gen.clone())) {
- return NumStrConv::neg_inf();
- }
- }
- last_accum = accum.clone();
- }
- None => match c {
- '_' if ignore_underscores => {}
- 'e' | 'E' | 'p' | 'P' => {
- exp_found = true;
- break; // start of exponent
- }
- '.' if fractional => {
- i += 1u; // skip the '.'
- break; // start of fractional part
- }
- _ => return None // invalid number
- }
- }
-
- i += 1u;
- }
-
- // Parse fractional part of number
- // Skip if already reached start of exponent
- if !exp_found {
- let mut power = _1.clone();
-
- while i < len {
- let c = buf[i] as char;
-
- match char::to_digit(c, radix) {
- Some(digit) => {
- // Decrease power one order of magnitude
- power = power / radix_gen;
-
- let digit_t: T = cast(digit).unwrap();
-
- // add/subtract current digit depending on sign
- if accum_positive {
- accum = accum + digit_t * power;
- } else {
- accum = accum - digit_t * power;
- }
-
- // Detect overflow by comparing to last value
- if accum_positive && accum < last_accum { return NumStrConv::inf(); }
- if !accum_positive && accum > last_accum { return NumStrConv::neg_inf(); }
- last_accum = accum.clone();
- }
- None => match c {
- '_' if ignore_underscores => {}
- 'e' | 'E' | 'p' | 'P' => {
- exp_found = true;
- break; // start of exponent
- }
- _ => return None // invalid number
- }
- }
-
- i += 1u;
- }
- }
-
- // Special case: buf not empty, but does not contain any digit in front
- // of the exponent sign -> number is empty string
- if i == start {
- if empty_zero {
- return Some(_0);
- } else {
- return None;
- }
- }
-
- let mut multiplier = _1.clone();
-
- if exp_found {
- let c = buf[i] as char;
- let base = match (c, exponent) {
- // c is never _ so don't need to handle specially
- ('e', ExpDec) | ('E', ExpDec) => 10u,
- ('p', ExpBin) | ('P', ExpBin) => 2u,
- _ => return None // char doesn't fit given exponent format
- };
-
- // parse remaining bytes as decimal integer,
- // skipping the exponent char
- let exp: Option<int> = from_str_bytes_common(
- buf.slice(i+1, len), 10, true, false, false, ExpNone, false,
- ignore_underscores);
-
- match exp {
- Some(exp_pow) => {
- multiplier = if exp_pow < 0 {
- _1 / pow_with_uint::<T>(base, (-exp_pow.to_int().unwrap()) as uint)
- } else {
- pow_with_uint::<T>(base, exp_pow.to_int().unwrap() as uint)
- }
- }
- None => return None // invalid exponent -> invalid number
- }
- }
-
- Some(accum * multiplier)
-}
-
-/**
- * Parses a string as a number. This is a wrapper for
- * `from_str_bytes_common()`, for details see there.
- */
-#[inline]
-pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+Mul<T,T>+
- Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv+Clone>(
- buf: &str, radix: uint, negative: bool, fractional: bool,
- special: bool, exponent: ExponentFormat, empty_zero: bool,
- ignore_underscores: bool
- ) -> Option<T> {
- from_str_bytes_common(buf.as_bytes(), radix, negative,
- fractional, special, exponent, empty_zero,
- ignore_underscores)
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use option::*;
-
- #[test]
- fn from_str_ignore_underscores() {
- let s : Option<u8> = from_str_common("__1__", 2, false, false, false,
- ExpNone, false, true);
- assert_eq!(s, Some(1u8));
-
- let n : Option<u8> = from_str_common("__1__", 2, false, false, false,
- ExpNone, false, false);
- assert_eq!(n, None);
-
- let f : Option<f32> = from_str_common("_1_._5_e_1_", 10, false, true, false,
- ExpDec, false, true);
- assert_eq!(f, Some(1.5e1f32));
- }
-
- #[test]
- fn from_str_issue5770() {
- // try to parse 0b1_1111_1111 = 511 as a u8. Caused problems
- // since 255*2+1 == 255 (mod 256) so the overflow wasn't
- // detected.
- let n : Option<u8> = from_str_common("111111111", 2, false, false, false,
- ExpNone, false, false);
- assert_eq!(n, None);
- }
-
- #[test]
- fn from_str_issue7588() {
- let u : Option<u8> = from_str_common("1000", 10, false, false, false,
- ExpNone, false, false);
- assert_eq!(u, None);
- let s : Option<i16> = from_str_common("80000", 10, false, false, false,
- ExpNone, false, false);
- assert_eq!(s, None);
- let f : Option<f32> = from_str_common(
- "10000000000000000000000000000000000000000", 10, false, false, false,
- ExpNone, false, false);
- assert_eq!(f, NumStrConv::inf())
- let fe : Option<f32> = from_str_common("1e40", 10, false, false, false,
- ExpDec, false, false);
- assert_eq!(fe, NumStrConv::inf())
- }
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
- use rand::{XorShiftRng, Rng};
- use to_str::ToStr;
- use f64;
-
- #[bench]
- fn uint_to_str_rand(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new();
- bh.iter(|| {
- rng.gen::<uint>().to_str();
- })
- }
-
- #[bench]
- fn float_to_str_rand(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new();
- bh.iter(|| {
- f64::to_str(rng.gen());
- })
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `u16`
-
-use num::{CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-uint_module!(u16, i16, 16)
-
-impl CheckedAdd for u16 {
- #[inline]
- fn checked_add(&self, v: &u16) -> Option<u16> {
- unsafe {
- let (x, y) = intrinsics::u16_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for u16 {
- #[inline]
- fn checked_sub(&self, v: &u16) -> Option<u16> {
- unsafe {
- let (x, y) = intrinsics::u16_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedMul for u16 {
- #[inline]
- fn checked_mul(&self, v: &u16) -> Option<u16> {
- unsafe {
- let (x, y) = intrinsics::u16_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `u32`
-
-use num::{CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-uint_module!(u32, i32, 32)
-
-impl CheckedAdd for u32 {
- #[inline]
- fn checked_add(&self, v: &u32) -> Option<u32> {
- unsafe {
- let (x, y) = intrinsics::u32_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for u32 {
- #[inline]
- fn checked_sub(&self, v: &u32) -> Option<u32> {
- unsafe {
- let (x, y) = intrinsics::u32_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedMul for u32 {
- #[inline]
- fn checked_mul(&self, v: &u32) -> Option<u32> {
- unsafe {
- let (x, y) = intrinsics::u32_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `u64`
-
-use num::{CheckedAdd, CheckedSub};
-#[cfg(target_word_size = "64")]
-use num::CheckedMul;
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-uint_module!(u64, i64, 64)
-
-impl CheckedAdd for u64 {
- #[inline]
- fn checked_add(&self, v: &u64) -> Option<u64> {
- unsafe {
- let (x, y) = intrinsics::u64_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for u64 {
- #[inline]
- fn checked_sub(&self, v: &u64) -> Option<u64> {
- unsafe {
- let (x, y) = intrinsics::u64_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-// FIXME: #8449: should not be disabled on 32-bit
-#[cfg(target_word_size = "64")]
-impl CheckedMul for u64 {
- #[inline]
- fn checked_mul(&self, v: &u64) -> Option<u64> {
- unsafe {
- let (x, y) = intrinsics::u64_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `u8`
-
-use num::{CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-
-pub use self::generated::*;
-
-uint_module!(u8, i8, 8)
-
-impl CheckedAdd for u8 {
- #[inline]
- fn checked_add(&self, v: &u8) -> Option<u8> {
- unsafe {
- let (x, y) = intrinsics::u8_add_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedSub for u8 {
- #[inline]
- fn checked_sub(&self, v: &u8) -> Option<u8> {
- unsafe {
- let (x, y) = intrinsics::u8_sub_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
-
-impl CheckedMul for u8 {
- #[inline]
- fn checked_mul(&self, v: &u8) -> Option<u8> {
- unsafe {
- let (x, y) = intrinsics::u8_mul_with_overflow(*self, *v);
- if y { None } else { Some(x) }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations and constants for `uint`
-
-use num;
-use num::{CheckedAdd, CheckedSub, CheckedMul};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-use mem;
-
-pub use self::generated::*;
-
-uint_module!(uint, int, ::int::bits)
-
-///
-/// Divide two numbers, return the result, rounded up.
-///
-/// # Arguments
-///
-/// * x - an integer
-/// * y - an integer distinct from 0u
-///
-/// # Return value
-///
-/// The smallest integer `q` such that `x/y <= q`.
-///
-pub fn div_ceil(x: uint, y: uint) -> uint {
- let div = x / y;
- if x % y == 0u { div }
- else { div + 1u }
-}
-
-///
-/// Divide two numbers, return the result, rounded to the closest integer.
-///
-/// # Arguments
-///
-/// * x - an integer
-/// * y - an integer distinct from 0u
-///
-/// # Return value
-///
-/// The integer `q` closest to `x/y`.
-///
-pub fn div_round(x: uint, y: uint) -> uint {
- let div = x / y;
- if x % y * 2u < y { div }
- else { div + 1u }
-}
-
-///
-/// Divide two numbers, return the result, rounded down.
-///
-/// Note: This is the same function as `div`.
-///
-/// # Arguments
-///
-/// * x - an integer
-/// * y - an integer distinct from 0u
-///
-/// # Return value
-///
-/// The smallest integer `q` such that `x/y <= q`. This
-/// is either `x/y` or `x/y + 1`.
-///
-pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
-
-impl num::Times for uint {
- #[inline]
- ///
- /// A convenience form for basic repetition. Given a uint `x`,
- /// `x.times(|| { ... })` executes the given block x times.
- ///
- /// Equivalent to `for uint::range(0, x) |_| { ... }`.
- ///
- /// Not defined on all integer types to permit unambiguous
- /// use with integer literals of inferred integer-type as
- /// the self-value (eg. `100.times(|| { ... })`).
- ///
- fn times(&self, it: ||) {
- let mut i = *self;
- while i > 0 {
- it();
- i -= 1;
- }
- }
-}
-
-/// Returns the smallest power of 2 greater than or equal to `n`
-#[inline]
-pub fn next_power_of_two(n: uint) -> uint {
- let halfbits: uint = mem::size_of::<uint>() * 4u;
- let mut tmp: uint = n - 1u;
- let mut shift: uint = 1u;
- while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
- tmp + 1u
-}
-
-/// Returns the smallest power of 2 greater than or equal to `n`
-#[inline]
-pub fn next_power_of_two_opt(n: uint) -> Option<uint> {
- let halfbits: uint = mem::size_of::<uint>() * 4u;
- let mut tmp: uint = n - 1u;
- let mut shift: uint = 1u;
- while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
- tmp.checked_add(&1)
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedAdd for uint {
- #[inline]
- fn checked_add(&self, v: &uint) -> Option<uint> {
- unsafe {
- let (x, y) = intrinsics::u32_add_with_overflow(*self as u32, *v as u32);
- if y { None } else { Some(x as uint) }
- }
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedAdd for uint {
- #[inline]
- fn checked_add(&self, v: &uint) -> Option<uint> {
- unsafe {
- let (x, y) = intrinsics::u64_add_with_overflow(*self as u64, *v as u64);
- if y { None } else { Some(x as uint) }
- }
- }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedSub for uint {
- #[inline]
- fn checked_sub(&self, v: &uint) -> Option<uint> {
- unsafe {
- let (x, y) = intrinsics::u32_sub_with_overflow(*self as u32, *v as u32);
- if y { None } else { Some(x as uint) }
- }
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedSub for uint {
- #[inline]
- fn checked_sub(&self, v: &uint) -> Option<uint> {
- unsafe {
- let (x, y) = intrinsics::u64_sub_with_overflow(*self as u64, *v as u64);
- if y { None } else { Some(x as uint) }
- }
- }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedMul for uint {
- #[inline]
- fn checked_mul(&self, v: &uint) -> Option<uint> {
- unsafe {
- let (x, y) = intrinsics::u32_mul_with_overflow(*self as u32, *v as u32);
- if y { None } else { Some(x as uint) }
- }
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedMul for uint {
- #[inline]
- fn checked_mul(&self, v: &uint) -> Option<uint> {
- unsafe {
- let (x, y) = intrinsics::u64_mul_with_overflow(*self as u64, *v as u64);
- if y { None } else { Some(x as uint) }
- }
- }
-}
-
-#[test]
-fn test_next_power_of_two() {
- assert!((next_power_of_two(0u) == 0u));
- assert!((next_power_of_two(1u) == 1u));
- assert!((next_power_of_two(2u) == 2u));
- assert!((next_power_of_two(3u) == 4u));
- assert!((next_power_of_two(4u) == 4u));
- assert!((next_power_of_two(5u) == 8u));
- assert!((next_power_of_two(6u) == 8u));
- assert!((next_power_of_two(7u) == 8u));
- assert!((next_power_of_two(8u) == 8u));
- assert!((next_power_of_two(9u) == 16u));
- assert!((next_power_of_two(10u) == 16u));
- assert!((next_power_of_two(11u) == 16u));
- assert!((next_power_of_two(12u) == 16u));
- assert!((next_power_of_two(13u) == 16u));
- assert!((next_power_of_two(14u) == 16u));
- assert!((next_power_of_two(15u) == 16u));
- assert!((next_power_of_two(16u) == 16u));
- assert!((next_power_of_two(17u) == 32u));
- assert!((next_power_of_two(18u) == 32u));
- assert!((next_power_of_two(19u) == 32u));
- assert!((next_power_of_two(20u) == 32u));
- assert!((next_power_of_two(21u) == 32u));
- assert!((next_power_of_two(22u) == 32u));
- assert!((next_power_of_two(23u) == 32u));
- assert!((next_power_of_two(24u) == 32u));
- assert!((next_power_of_two(25u) == 32u));
- assert!((next_power_of_two(26u) == 32u));
- assert!((next_power_of_two(27u) == 32u));
- assert!((next_power_of_two(28u) == 32u));
- assert!((next_power_of_two(29u) == 32u));
- assert!((next_power_of_two(30u) == 32u));
- assert!((next_power_of_two(31u) == 32u));
- assert!((next_power_of_two(32u) == 32u));
- assert!((next_power_of_two(33u) == 64u));
- assert!((next_power_of_two(34u) == 64u));
- assert!((next_power_of_two(35u) == 64u));
- assert!((next_power_of_two(36u) == 64u));
- assert!((next_power_of_two(37u) == 64u));
- assert!((next_power_of_two(38u) == 64u));
- assert!((next_power_of_two(39u) == 64u));
-}
-
-#[test]
-fn test_overflows() {
- use uint;
- assert!((uint::max_value > 0u));
- assert!((uint::min_value <= 0u));
- assert!((uint::min_value + uint::max_value + 1u == 0u));
-}
-
-#[test]
-fn test_div() {
- assert!((div_floor(3u, 4u) == 0u));
- assert!((div_ceil(3u, 4u) == 1u));
- assert!((div_round(3u, 4u) == 1u));
-}
-
-#[test]
-pub fn test_times() {
- use num::Times;
- let ten = 10 as uint;
- let mut accum = 0;
- ten.times(|| { accum += 1; });
- assert!((accum == 10));
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// FIXME(#4375): this shouldn't have to be a nested module named 'generated'
-
-#[macro_escape];
-#[doc(hidden)];
-
-macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
-
-#[allow(non_uppercase_statics)];
-
-use default::Default;
-use num::BitCount;
-use num::{ToStrRadix, FromStrRadix};
-use num::{CheckedDiv, Zero, One, strconv};
-use prelude::*;
-use str;
-
-pub use cmp::{min, max};
-
-pub static bits : uint = $bits;
-pub static bytes : uint = ($bits / 8);
-
-pub static min_value: $T = 0 as $T;
-pub static max_value: $T = 0 as $T - 1 as $T;
-
-impl CheckedDiv for $T {
- #[inline]
- fn checked_div(&self, v: &$T) -> Option<$T> {
- if *v == 0 {
- None
- } else {
- Some(self / *v)
- }
- }
-}
-
-impl Num for $T {}
-
-#[cfg(not(test))]
-impl Ord for $T {
- #[inline]
- fn lt(&self, other: &$T) -> bool { (*self) < (*other) }
-}
-
-#[cfg(not(test))]
-impl Eq for $T {
- #[inline]
- fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
-}
-
-impl Orderable for $T {
- #[inline]
- fn min(&self, other: &$T) -> $T {
- if *self < *other { *self } else { *other }
- }
-
- #[inline]
- fn max(&self, other: &$T) -> $T {
- if *self > *other { *self } else { *other }
- }
-
- /// Returns the number constrained within the range `mn <= self <= mx`.
- #[inline]
- fn clamp(&self, mn: &$T, mx: &$T) -> $T {
- match () {
- _ if (*self > *mx) => *mx,
- _ if (*self < *mn) => *mn,
- _ => *self,
- }
- }
-}
-
-impl Default for $T {
- #[inline]
- fn default() -> $T { 0 }
-}
-
-impl Zero for $T {
- #[inline]
- fn zero() -> $T { 0 }
-
- #[inline]
- fn is_zero(&self) -> bool { *self == 0 }
-}
-
-impl One for $T {
- #[inline]
- fn one() -> $T { 1 }
-}
-
-#[cfg(not(test))]
-impl Add<$T,$T> for $T {
- #[inline]
- fn add(&self, other: &$T) -> $T { *self + *other }
-}
-
-#[cfg(not(test))]
-impl Sub<$T,$T> for $T {
- #[inline]
- fn sub(&self, other: &$T) -> $T { *self - *other }
-}
-
-#[cfg(not(test))]
-impl Mul<$T,$T> for $T {
- #[inline]
- fn mul(&self, other: &$T) -> $T { *self * *other }
-}
-
-#[cfg(not(test))]
-impl Div<$T,$T> for $T {
- #[inline]
- fn div(&self, other: &$T) -> $T { *self / *other }
-}
-
-#[cfg(not(test))]
-impl Rem<$T,$T> for $T {
- #[inline]
- fn rem(&self, other: &$T) -> $T { *self % *other }
-}
-
-#[cfg(not(test))]
-impl Neg<$T> for $T {
- #[inline]
- fn neg(&self) -> $T { -*self }
-}
-
-impl Unsigned for $T {}
-
-impl Integer for $T {
- /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
- #[inline]
- fn div_rem(&self, other: &$T) -> ($T,$T) {
- (*self / *other, *self % *other)
- }
-
- /// Unsigned integer division. Returns the same result as `div` (`/`).
- #[inline]
- fn div_floor(&self, other: &$T) -> $T { *self / *other }
-
- /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
- #[inline]
- fn mod_floor(&self, other: &$T) -> $T { *self % *other }
-
- /// Calculates `div_floor` and `mod_floor` simultaneously
- #[inline]
- fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
- (*self / *other, *self % *other)
- }
-
- /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
- #[inline]
- fn gcd(&self, other: &$T) -> $T {
- // Use Euclid's algorithm
- let mut m = *self;
- let mut n = *other;
- while m != 0 {
- let temp = m;
- m = n % temp;
- n = temp;
- }
- n
- }
-
- /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
- #[inline]
- fn lcm(&self, other: &$T) -> $T {
- (*self * *other) / self.gcd(other)
- }
-
- /// Returns `true` if the number can be divided by `other` without leaving a remainder
- #[inline]
- fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
-
- /// Returns `true` if the number is divisible by `2`
- #[inline]
- fn is_even(&self) -> bool { self.is_multiple_of(&2) }
-
- /// Returns `true` if the number is not divisible by `2`
- #[inline]
- fn is_odd(&self) -> bool { !self.is_even() }
-}
-
-impl Bitwise for $T {}
-
-#[cfg(not(test))]
-impl BitOr<$T,$T> for $T {
- #[inline]
- fn bitor(&self, other: &$T) -> $T { *self | *other }
-}
-
-#[cfg(not(test))]
-impl BitAnd<$T,$T> for $T {
- #[inline]
- fn bitand(&self, other: &$T) -> $T { *self & *other }
-}
-
-#[cfg(not(test))]
-impl BitXor<$T,$T> for $T {
- #[inline]
- fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
-}
-
-#[cfg(not(test))]
-impl Shl<$T,$T> for $T {
- #[inline]
- fn shl(&self, other: &$T) -> $T { *self << *other }
-}
-
-#[cfg(not(test))]
-impl Shr<$T,$T> for $T {
- #[inline]
- fn shr(&self, other: &$T) -> $T { *self >> *other }
-}
-
-#[cfg(not(test))]
-impl Not<$T> for $T {
- #[inline]
- fn not(&self) -> $T { !*self }
-}
-
-impl Bounded for $T {
- #[inline]
- fn min_value() -> $T { min_value }
-
- #[inline]
- fn max_value() -> $T { max_value }
-}
-
-impl Int for $T {}
-
-// String conversion functions and impl str -> num
-
-/// Parse a byte slice as a number in the given base.
-#[inline]
-pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
- strconv::from_str_bytes_common(buf, radix, false, false, false,
- strconv::ExpNone, false, false)
-}
-
-impl FromStr for $T {
- #[inline]
- fn from_str(s: &str) -> Option<$T> {
- strconv::from_str_common(s, 10u, false, false, false,
- strconv::ExpNone, false, false)
- }
-}
-
-impl FromStrRadix for $T {
- #[inline]
- fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
- strconv::from_str_common(s, radix, false, false, false,
- strconv::ExpNone, false, false)
- }
-}
-
-// String conversion functions and impl num -> str
-
-/// Convert to a string as a byte slice in a given base.
-#[inline]
-pub fn to_str_bytes<U>(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U {
- // The radix can be as low as 2, so we need at least 64 characters for a
- // base 2 number.
- let mut buf = [0u8, ..64];
- let mut cur = 0;
- strconv::int_to_str_bytes_common(n, radix, strconv::SignNone, |i| {
- buf[cur] = i;
- cur += 1;
- });
- f(buf.slice(0, cur))
-}
-
-impl ToStr for $T {
- /// Convert to a string in base 10.
- #[inline]
- fn to_str(&self) -> ~str {
- self.to_str_radix(10u)
- }
-}
-
-impl ToStrRadix for $T {
- /// Convert to a string in a given base.
- #[inline]
- fn to_str_radix(&self, radix: uint) -> ~str {
- let mut buf = ~[];
- strconv::int_to_str_bytes_common(*self, radix, strconv::SignNone, |i| {
- buf.push(i);
- });
- // We know we generated valid utf-8, so we don't need to go through that
- // check.
- unsafe { str::raw::from_utf8_owned(buf) }
- }
-}
-
-impl Primitive for $T {
- #[inline]
- fn bits(_: Option<$T>) -> uint { bits }
-
- #[inline]
- fn bytes(_: Option<$T>) -> uint { bits / 8 }
-
- #[inline]
- fn is_signed(_: Option<$T>) -> bool { false }
-}
-
-impl BitCount for $T {
- /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
- #[inline]
- fn population_count(&self) -> $T {
- (*self as $T_SIGNED).population_count() as $T
- }
-
- /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
- #[inline]
- fn leading_zeros(&self) -> $T {
- (*self as $T_SIGNED).leading_zeros() as $T
- }
-
- /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
- #[inline]
- fn trailing_zeros(&self) -> $T {
- (*self as $T_SIGNED).trailing_zeros() as $T
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use super::*;
-
- use num;
- use mem;
- use u16;
-
- #[test]
- fn test_num() {
- num::test_num(10 as $T, 2 as $T);
- }
-
- #[test]
- fn test_orderable() {
- assert_eq!((1 as $T).min(&(2 as $T)), 1 as $T);
- assert_eq!((2 as $T).min(&(1 as $T)), 1 as $T);
- assert_eq!((1 as $T).max(&(2 as $T)), 2 as $T);
- assert_eq!((2 as $T).max(&(1 as $T)), 2 as $T);
- assert_eq!((1 as $T).clamp(&(2 as $T), &(4 as $T)), 2 as $T);
- assert_eq!((8 as $T).clamp(&(2 as $T), &(4 as $T)), 4 as $T);
- assert_eq!((3 as $T).clamp(&(2 as $T), &(4 as $T)), 3 as $T);
- }
-
- #[test]
- fn test_div_mod_floor() {
- assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
- assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
- assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
- assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
- assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
- assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
- assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
- assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
- assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
- }
-
- #[test]
- fn test_gcd() {
- assert_eq!((10 as $T).gcd(&2), 2 as $T);
- assert_eq!((10 as $T).gcd(&3), 1 as $T);
- assert_eq!((0 as $T).gcd(&3), 3 as $T);
- assert_eq!((3 as $T).gcd(&3), 3 as $T);
- assert_eq!((56 as $T).gcd(&42), 14 as $T);
- }
-
- #[test]
- fn test_lcm() {
- assert_eq!((1 as $T).lcm(&0), 0 as $T);
- assert_eq!((0 as $T).lcm(&1), 0 as $T);
- assert_eq!((1 as $T).lcm(&1), 1 as $T);
- assert_eq!((8 as $T).lcm(&9), 72 as $T);
- assert_eq!((11 as $T).lcm(&5), 55 as $T);
- assert_eq!((99 as $T).lcm(&17), 1683 as $T);
- }
-
- #[test]
- fn test_multiple_of() {
- assert!((6 as $T).is_multiple_of(&(6 as $T)));
- assert!((6 as $T).is_multiple_of(&(3 as $T)));
- assert!((6 as $T).is_multiple_of(&(1 as $T)));
- }
-
- #[test]
- fn test_even() {
- assert_eq!((0 as $T).is_even(), true);
- assert_eq!((1 as $T).is_even(), false);
- assert_eq!((2 as $T).is_even(), true);
- assert_eq!((3 as $T).is_even(), false);
- assert_eq!((4 as $T).is_even(), true);
- }
-
- #[test]
- fn test_odd() {
- assert_eq!((0 as $T).is_odd(), false);
- assert_eq!((1 as $T).is_odd(), true);
- assert_eq!((2 as $T).is_odd(), false);
- assert_eq!((3 as $T).is_odd(), true);
- assert_eq!((4 as $T).is_odd(), false);
- }
-
- #[test]
- fn test_bitwise() {
- assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
- assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
- assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
- assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
- assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
- assert_eq!(max_value - (0b1011 as $T), (0b1011 as $T).not());
- }
-
- #[test]
- fn test_bitcount() {
- assert_eq!((0b010101 as $T).population_count(), 3);
- }
-
- #[test]
- fn test_primitive() {
- let none: Option<$T> = None;
- assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8);
- assert_eq!(Primitive::bytes(none), mem::size_of::<$T>());
- }
-
- #[test]
- pub fn test_to_str() {
- assert_eq!((0 as $T).to_str_radix(10u), ~"0");
- assert_eq!((1 as $T).to_str_radix(10u), ~"1");
- assert_eq!((2 as $T).to_str_radix(10u), ~"2");
- assert_eq!((11 as $T).to_str_radix(10u), ~"11");
- assert_eq!((11 as $T).to_str_radix(16u), ~"b");
- assert_eq!((255 as $T).to_str_radix(16u), ~"ff");
- assert_eq!((0xff as $T).to_str_radix(10u), ~"255");
- }
-
- #[test]
- pub fn test_from_str() {
- assert_eq!(from_str::<$T>("0"), Some(0u as $T));
- assert_eq!(from_str::<$T>("3"), Some(3u as $T));
- assert_eq!(from_str::<$T>("10"), Some(10u as $T));
- assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
- assert_eq!(from_str::<$T>("00100"), Some(100u as $T));
-
- assert!(from_str::<$T>("").is_none());
- assert!(from_str::<$T>(" ").is_none());
- assert!(from_str::<$T>("x").is_none());
- }
-
- #[test]
- pub fn test_parse_bytes() {
- use str::StrSlice;
- assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123u as $T));
- assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9u as $T));
- assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83u as $T));
- assert_eq!(u16::parse_bytes("123".as_bytes(), 16u), Some(291u as u16));
- assert_eq!(u16::parse_bytes("ffff".as_bytes(), 16u), Some(65535u as u16));
- assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35u as $T));
-
- assert!(parse_bytes("Z".as_bytes(), 10u).is_none());
- assert!(parse_bytes("_".as_bytes(), 2u).is_none());
- }
-
- #[test]
- fn test_uint_to_str_overflow() {
- let mut u8_val: u8 = 255_u8;
- assert_eq!(u8_val.to_str(), ~"255");
-
- u8_val += 1 as u8;
- assert_eq!(u8_val.to_str(), ~"0");
-
- let mut u16_val: u16 = 65_535_u16;
- assert_eq!(u16_val.to_str(), ~"65535");
-
- u16_val += 1 as u16;
- assert_eq!(u16_val.to_str(), ~"0");
-
- let mut u32_val: u32 = 4_294_967_295_u32;
- assert_eq!(u32_val.to_str(), ~"4294967295");
-
- u32_val += 1 as u32;
- assert_eq!(u32_val.to_str(), ~"0");
-
- let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
- assert_eq!(u64_val.to_str(), ~"18446744073709551615");
-
- u64_val += 1 as u64;
- assert_eq!(u64_val.to_str(), ~"0");
- }
-
- #[test]
- fn test_uint_from_str_overflow() {
- let mut u8_val: u8 = 255_u8;
- assert_eq!(from_str::<u8>("255"), Some(u8_val));
- assert!(from_str::<u8>("256").is_none());
-
- u8_val += 1 as u8;
- assert_eq!(from_str::<u8>("0"), Some(u8_val));
- assert!(from_str::<u8>("-1").is_none());
-
- let mut u16_val: u16 = 65_535_u16;
- assert_eq!(from_str::<u16>("65535"), Some(u16_val));
- assert!(from_str::<u16>("65536").is_none());
-
- u16_val += 1 as u16;
- assert_eq!(from_str::<u16>("0"), Some(u16_val));
- assert!(from_str::<u16>("-1").is_none());
-
- let mut u32_val: u32 = 4_294_967_295_u32;
- assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
- assert!(from_str::<u32>("4294967296").is_none());
-
- u32_val += 1 as u32;
- assert_eq!(from_str::<u32>("0"), Some(u32_val));
- assert!(from_str::<u32>("-1").is_none());
-
- let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
- assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
- assert!(from_str::<u64>("18446744073709551616").is_none());
-
- u64_val += 1 as u64;
- assert_eq!(from_str::<u64>("0"), Some(u64_val));
- assert!(from_str::<u64>("-1").is_none());
- }
-
- #[test]
- #[should_fail]
- pub fn to_str_radix1() {
- 100u.to_str_radix(1u);
- }
-
- #[test]
- #[should_fail]
- pub fn to_str_radix37() {
- 100u.to_str_radix(37u);
- }
-
- #[test]
- fn test_unsigned_checked_div() {
- assert_eq!(10u.checked_div(&2), Some(5));
- assert_eq!(5u.checked_div(&0), None);
- }
-}
-
-}))
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// So we don't have to document the actual methods on the traits.
-#[allow(missing_doc)];
-
-/*!
- *
- * Traits for the built-in operators. Implementing these traits allows you to get
- * an effect similar to overloading operators.
- *
- * The values for the right hand side of an operator are automatically
- * borrowed, so `a + b` is sugar for `a.add(&b)`.
- *
- * All of these traits are imported by the prelude, so they are available in
- * every Rust program.
- *
- * # Example
- *
- * This example creates a `Point` struct that implements `Add` and `Sub`, and then
- * demonstrates adding and subtracting two `Point`s.
- *
- * ```rust
- * struct Point {
- * x: int,
- * y: int
- * }
- *
- * impl Add<Point, Point> for Point {
- * fn add(&self, other: &Point) -> Point {
- * Point {x: self.x + other.x, y: self.y + other.y}
- * }
- * }
- *
- * impl Sub<Point, Point> for Point {
- * fn sub(&self, other: &Point) -> Point {
- * Point {x: self.x - other.x, y: self.y - other.y}
- * }
- * }
- * fn main() {
- * println(format!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}));
- * println(format!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3}));
- * }
- * ```
- *
- * See the documentation for each trait for a minimum implementation that prints
- * something to the screen.
- *
- */
-
-/**
- *
- * The `Drop` trait is used to run some code when a value goes out of scope. This
- * is sometimes called a 'destructor'.
- *
- * # Example
- *
- * A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
- * out of scope, and therefore `main` prints `Dropping!`.
- *
- * ```rust
- * struct HasDrop;
- *
- * impl Drop for HasDrop {
- * fn drop(&mut self) {
- * println("Dropping!");
- * }
- * }
- *
- * fn main() {
- * let _x = HasDrop;
- * }
- * ```
- */
-#[lang="drop"]
-pub trait Drop {
- fn drop(&mut self);
-}
-
-/**
- *
- * The `Add` trait is used to specify the functionality of `+`.
- *
- * # Example
- *
- * A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
- * calling `add`, and therefore, `main` prints `Adding!`.
- *
- * ```rust
- * struct Foo;
- *
- * impl Add<Foo, Foo> for Foo {
- * fn add(&self, _rhs: &Foo) -> Foo {
- * println("Adding!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo + Foo;
- * }
- * ```
- */
-#[lang="add"]
-pub trait Add<RHS,Result> {
- fn add(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Sub` trait is used to specify the functionality of `-`.
- *
- * # Example
- *
- * A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
- * calling `sub`, and therefore, `main` prints `Subtracting!`.
- *
- * ```rust
- * struct Foo;
- *
- * impl Sub<Foo, Foo> for Foo {
- * fn sub(&self, _rhs: &Foo) -> Foo {
- * println("Subtracting!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo - Foo;
- * }
- * ```
- */
-#[lang="sub"]
-pub trait Sub<RHS,Result> {
- fn sub(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Mul` trait is used to specify the functionality of `*`.
- *
- * # Example
- *
- * A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
- * calling `mul`, and therefore, `main` prints `Multiplying!`.
- *
- * ```rust
- * struct Foo;
- *
- * impl Mul<Foo, Foo> for Foo {
- * fn mul(&self, _rhs: &Foo) -> Foo {
- * println("Multiplying!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo * Foo;
- * }
- * ```
- */
-#[lang="mul"]
-pub trait Mul<RHS,Result> {
- fn mul(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Div` trait is used to specify the functionality of `/`.
- *
- * # Example
- *
- * A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
- * calling `div`, and therefore, `main` prints `Dividing!`.
- *
- * ```
- * struct Foo;
- *
- * impl Div<Foo, Foo> for Foo {
- * fn div(&self, _rhs: &Foo) -> Foo {
- * println("Dividing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo / Foo;
- * }
- * ```
- */
-#[lang="div"]
-pub trait Div<RHS,Result> {
- fn div(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Rem` trait is used to specify the functionality of `%`.
- *
- * # Example
- *
- * A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
- * calling `rem`, and therefore, `main` prints `Remainder-ing!`.
- *
- * ```
- * struct Foo;
- *
- * impl Rem<Foo, Foo> for Foo {
- * fn rem(&self, _rhs: &Foo) -> Foo {
- * println("Remainder-ing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo % Foo;
- * }
- * ```
- */
-#[lang="rem"]
-pub trait Rem<RHS,Result> {
- fn rem(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Neg` trait is used to specify the functionality of unary `-`.
- *
- * # Example
- *
- * A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
- * `neg`, and therefore, `main` prints `Negating!`.
- *
- * ```
- * struct Foo;
- *
- * impl Neg<Foo> for Foo {
- * fn neg(&self) -> Foo {
- * println("Negating!");
- * *self
- * }
- * }
- *
- * fn main() {
- * -Foo;
- * }
- * ```
- */
-#[lang="neg"]
-pub trait Neg<Result> {
- fn neg(&self) -> Result;
-}
-
-/**
- *
- * The `Not` trait is used to specify the functionality of unary `!`.
- *
- * # Example
- *
- * A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
- * `not`, and therefore, `main` prints `Not-ing!`.
- *
- * ```
- * struct Foo;
- *
- * impl Not<Foo> for Foo {
- * fn not(&self) -> Foo {
- * println("Not-ing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * !Foo;
- * }
- * ```
- */
-#[lang="not"]
-pub trait Not<Result> {
- fn not(&self) -> Result;
-}
-
-/**
- *
- * The `BitAnd` trait is used to specify the functionality of `&`.
- *
- * # Example
- *
- * A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
- * calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
- *
- * ```
- * struct Foo;
- *
- * impl BitAnd<Foo, Foo> for Foo {
- * fn bitand(&self, _rhs: &Foo) -> Foo {
- * println("Bitwise And-ing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo & Foo;
- * }
- * ```
- */
-#[lang="bitand"]
-pub trait BitAnd<RHS,Result> {
- fn bitand(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `BitOr` trait is used to specify the functionality of `|`.
- *
- * # Example
- *
- * A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
- * calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
- *
- * ```
- * struct Foo;
- *
- * impl BitOr<Foo, Foo> for Foo {
- * fn bitor(&self, _rhs: &Foo) -> Foo {
- * println("Bitwise Or-ing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo | Foo;
- * }
- * ```
- */
-#[lang="bitor"]
-pub trait BitOr<RHS,Result> {
- fn bitor(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `BitXor` trait is used to specify the functionality of `^`.
- *
- * # Example
- *
- * A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
- * calling `bixtor`, and therefore, `main` prints `Bitwise Xor-ing!`.
- *
- * ```
- * struct Foo;
- *
- * impl BitXor<Foo, Foo> for Foo {
- * fn bitxor(&self, _rhs: &Foo) -> Foo {
- * println("Bitwise Xor-ing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo ^ Foo;
- * }
- * ```
- */
-#[lang="bitxor"]
-pub trait BitXor<RHS,Result> {
- fn bitxor(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Shl` trait is used to specify the functionality of `<<`.
- *
- * # Example
- *
- * A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
- * calling `shl`, and therefore, `main` prints `Shifting left!`.
- *
- * ```
- * struct Foo;
- *
- * impl Shl<Foo, Foo> for Foo {
- * fn shl(&self, _rhs: &Foo) -> Foo {
- * println("Shifting left!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo << Foo;
- * }
- * ```
- */
-#[lang="shl"]
-pub trait Shl<RHS,Result> {
- fn shl(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Shr` trait is used to specify the functionality of `>>`.
- *
- * # Example
- *
- * A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
- * calling `shr`, and therefore, `main` prints `Shifting right!`.
- *
- * ```
- * struct Foo;
- *
- * impl Shr<Foo, Foo> for Foo {
- * fn shr(&self, _rhs: &Foo) -> Foo {
- * println("Shifting right!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo >> Foo;
- * }
- * ```
- */
-#[lang="shr"]
-pub trait Shr<RHS,Result> {
- fn shr(&self, rhs: &RHS) -> Result;
-}
-
-/**
- *
- * The `Index` trait is used to specify the functionality of indexing operations
- * like `arr[idx]`.
- *
- * # Example
- *
- * A trivial implementation of `Index`. When `Foo[Foo]` happens, it ends up
- * calling `index`, and therefore, `main` prints `Indexing!`.
- *
- * ```
- * struct Foo;
- *
- * impl Index<Foo, Foo> for Foo {
- * fn index(&self, _rhs: &Foo) -> Foo {
- * println("Indexing!");
- * *self
- * }
- * }
- *
- * fn main() {
- * Foo[Foo];
- * }
- * ```
- */
-#[lang="index"]
-pub trait Index<Index,Result> {
- fn index(&self, index: &Index) -> Result;
-}
-
-#[cfg(test)]
-mod bench {
-
- use extra::test::BenchHarness;
- use ops::Drop;
-
- // Overhead of dtors
-
- struct HasDtor {
- x: int
- }
-
- impl Drop for HasDtor {
- fn drop(&mut self) {
- }
- }
-
- #[bench]
- fn alloc_obj_with_dtor(bh: &mut BenchHarness) {
- bh.iter(|| {
- HasDtor { x : 10 };
- })
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations on the ubiquitous `Option` type.
-//!
-//! Type `Option` represents an optional value.
-//!
-//! Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
-//! languages you might use a nullable type, in Rust you would use an option
-//! type.
-//!
-//! Options are most commonly used with pattern matching to query the presence
-//! of a value and take action, always accounting for the `None` case.
-//!
-//! # Example
-//!
-//! ```
-//! let msg = Some(~"howdy");
-//!
-//! // Take a reference to the contained string
-//! match msg {
-//! Some(ref m) => io::println(*m),
-//! None => ()
-//! }
-//!
-//! // Remove the contained string, destroying the Option
-//! let unwrapped_msg = match msg {
-//! Some(m) => m,
-//! None => ~"default message"
-//! };
-//! ```
-
-use any::Any;
-use clone::Clone;
-use clone::DeepClone;
-use cmp::{Eq, TotalEq, TotalOrd};
-use default::Default;
-use fmt;
-use iter::{Iterator, DoubleEndedIterator, ExactSize};
-use kinds::Send;
-use result::{IntoResult, ToResult, AsResult};
-use result::{Result, Ok, Err};
-use str::OwnedStr;
-use to_str::ToStr;
-use util;
-
-/// The option type
-#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
-pub enum Option<T> {
- /// No value
- None,
- /// Some value `T`
- Some(T)
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Type implementation
-/////////////////////////////////////////////////////////////////////////////
-
-impl<T> Option<T> {
- /////////////////////////////////////////////////////////////////////////
- // Querying the contained values
- /////////////////////////////////////////////////////////////////////////
-
- /// Returns true if the option contains a `Some` value
- #[inline]
- pub fn is_some(&self) -> bool {
- match *self {
- Some(_) => true,
- None => false
- }
- }
-
- /// Returns true if the option equals `None`
- #[inline]
- pub fn is_none(&self) -> bool {
- !self.is_some()
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Adapter for working with references
- /////////////////////////////////////////////////////////////////////////
-
- /// Convert from `Option<T>` to `Option<&T>`
- #[inline]
- pub fn as_ref<'r>(&'r self) -> Option<&'r T> {
- match *self { Some(ref x) => Some(x), None => None }
- }
-
- /// Convert from `Option<T>` to `Option<&mut T>`
- #[inline]
- pub fn as_mut<'r>(&'r mut self) -> Option<&'r mut T> {
- match *self { Some(ref mut x) => Some(x), None => None }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Getting to contained values
- /////////////////////////////////////////////////////////////////////////
-
- /// Unwraps a option, yielding the content of a `Some`
- /// Fails if the value is a `None` with a custom failure message provided by `msg`.
- #[inline]
- pub fn expect<M: Any + Send>(self, msg: M) -> T {
- match self {
- Some(val) => val,
- None => fail!(msg),
- }
- }
-
- /// Moves a value out of an option type and returns it.
- ///
- /// Useful primarily for getting strings, vectors and unique pointers out
- /// of option types without copying them.
- ///
- /// # Failure
- ///
- /// Fails if the value equals `None`.
- ///
- /// # Safety note
- ///
- /// In general, because this function may fail, its use is discouraged.
- /// Instead, prefer to use pattern matching and handle the `None`
- /// case explicitly.
- #[inline]
- pub fn unwrap(self) -> T {
- match self {
- Some(val) => val,
- None => fail!("called `Option::unwrap()` on a `None` value"),
- }
- }
-
- /// Returns the contained value or a default
- #[inline]
- pub fn unwrap_or(self, def: T) -> T {
- match self {
- Some(x) => x,
- None => def
- }
- }
-
- /// Returns the contained value or computes it from a closure
- #[inline]
- pub fn unwrap_or_else(self, f: || -> T) -> T {
- match self {
- Some(x) => x,
- None => f()
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Transforming contained values
- /////////////////////////////////////////////////////////////////////////
-
- /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value.
- #[inline]
- pub fn map<U>(self, f: |T| -> U) -> Option<U> {
- match self { Some(x) => Some(f(x)), None => None }
- }
-
- /// Applies a function to the contained value or returns a default.
- #[inline]
- pub fn map_default<U>(self, def: U, f: |T| -> U) -> U {
- match self { None => def, Some(t) => f(t) }
- }
-
- /// Apply a function to the contained value or do nothing.
- /// Returns true if the contained value was mutated.
- pub fn mutate(&mut self, f: |T| -> T) -> bool {
- if self.is_some() {
- *self = Some(f(self.take_unwrap()));
- true
- } else { false }
- }
-
- /// Apply a function to the contained value or set it to a default.
- /// Returns true if the contained value was mutated, or false if set to the default.
- pub fn mutate_default(&mut self, def: T, f: |T| -> T) -> bool {
- if self.is_some() {
- *self = Some(f(self.take_unwrap()));
- true
- } else {
- *self = Some(def);
- false
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Iterator constructors
- /////////////////////////////////////////////////////////////////////////
-
- /// Return an iterator over the possibly contained value
- #[inline]
- pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
- match *self {
- Some(ref x) => OptionIterator{opt: Some(x)},
- None => OptionIterator{opt: None}
- }
- }
-
- /// Return a mutable iterator over the possibly contained value
- #[inline]
- pub fn mut_iter<'r>(&'r mut self) -> OptionIterator<&'r mut T> {
- match *self {
- Some(ref mut x) => OptionIterator{opt: Some(x)},
- None => OptionIterator{opt: None}
- }
- }
-
- /// Return a consuming iterator over the possibly contained value
- #[inline]
- pub fn move_iter(self) -> OptionIterator<T> {
- OptionIterator{opt: self}
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Boolean operations on the values, eager and lazy
- /////////////////////////////////////////////////////////////////////////
-
- /// Returns `None` if the option is `None`, otherwise returns `optb`.
- #[inline]
- pub fn and<U>(self, optb: Option<U>) -> Option<U> {
- match self {
- Some(_) => optb,
- None => None,
- }
- }
-
- /// Returns `None` if the option is `None`, otherwise calls `f` with the
- /// wrapped value and returns the result.
- #[inline]
- pub fn and_then<U>(self, f: |T| -> Option<U>) -> Option<U> {
- match self {
- Some(x) => f(x),
- None => None,
- }
- }
-
- /// Returns the option if it contains a value, otherwise returns `optb`.
- #[inline]
- pub fn or(self, optb: Option<T>) -> Option<T> {
- match self {
- Some(_) => self,
- None => optb
- }
- }
-
- /// Returns the option if it contains a value, otherwise calls `f` and
- /// returns the result.
- #[inline]
- pub fn or_else(self, f: || -> Option<T>) -> Option<T> {
- match self {
- Some(_) => self,
- None => f(),
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Misc
- /////////////////////////////////////////////////////////////////////////
-
- /// Take the value out of the option, leaving a `None` in its place.
- #[inline]
- pub fn take(&mut self) -> Option<T> {
- util::replace(self, None)
- }
-
- /// Filters an optional value using a given function.
- #[inline(always)]
- pub fn filtered(self, f: |t: &T| -> bool) -> Option<T> {
- match self {
- Some(x) => if(f(&x)) {Some(x)} else {None},
- None => None
- }
- }
-
- /// Applies a function zero or more times until the result is `None`.
- #[inline]
- pub fn while_some(self, blk: |v: T| -> Option<T>) {
- let mut opt = self;
- while opt.is_some() {
- opt = blk(opt.unwrap());
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Common special cases
- /////////////////////////////////////////////////////////////////////////
-
- /// The option dance. Moves a value out of an option type and returns it,
- /// replacing the original with `None`.
- ///
- /// # Failure
- ///
- /// Fails if the value equals `None`.
- #[inline]
- pub fn take_unwrap(&mut self) -> T {
- if self.is_none() {
- fail!("called `Option::take_unwrap()` on a `None` value")
- }
- self.take().unwrap()
- }
-
- /// Gets an immutable reference to the value inside an option.
- ///
- /// # Failure
- ///
- /// Fails if the value equals `None`
- ///
- /// # Safety note
- ///
- /// In general, because this function may fail, its use is discouraged
- /// (calling `get` on `None` is akin to dereferencing a null pointer).
- /// Instead, prefer to use pattern matching and handle the `None`
- /// case explicitly.
- #[inline]
- pub fn get_ref<'a>(&'a self) -> &'a T {
- match *self {
- Some(ref x) => x,
- None => fail!("called `Option::get_ref()` on a `None` value"),
- }
- }
-
- /// Gets a mutable reference to the value inside an option.
- ///
- /// # Failure
- ///
- /// Fails if the value equals `None`
- ///
- /// # Safety note
- ///
- /// In general, because this function may fail, its use is discouraged
- /// (calling `get` on `None` is akin to dereferencing a null pointer).
- /// Instead, prefer to use pattern matching and handle the `None`
- /// case explicitly.
- #[inline]
- pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
- match *self {
- Some(ref mut x) => x,
- None => fail!("called `Option::get_mut_ref()` on a `None` value"),
- }
- }
-}
-
-impl<T: Default> Option<T> {
- /// Returns the contained value or default (for this type)
- #[inline]
- pub fn unwrap_or_default(self) -> T {
- match self {
- Some(x) => x,
- None => Default::default()
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Constructor extension trait
-/////////////////////////////////////////////////////////////////////////////
-
-/// A generic trait for converting a value to a `Option`
-pub trait ToOption<T> {
- /// Convert to the `option` type
- fn to_option(&self) -> Option<T>;
-}
-
-/// A generic trait for converting a value to a `Option`
-pub trait IntoOption<T> {
- /// Convert to the `option` type
- fn into_option(self) -> Option<T>;
-}
-
-/// A generic trait for converting a value to a `Option`
-pub trait AsOption<T> {
- /// Convert to the `option` type
- fn as_option<'a>(&'a self) -> Option<&'a T>;
-}
-
-impl<T: Clone> ToOption<T> for Option<T> {
- #[inline]
- fn to_option(&self) -> Option<T> { self.clone() }
-}
-
-impl<T> IntoOption<T> for Option<T> {
- #[inline]
- fn into_option(self) -> Option<T> { self }
-}
-
-impl<T> AsOption<T> for Option<T> {
- #[inline]
- fn as_option<'a>(&'a self) -> Option<&'a T> {
- match *self {
- Some(ref x) => Some(x),
- None => None,
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Trait implementations
-/////////////////////////////////////////////////////////////////////////////
-
-impl<T: Clone> ToResult<T, ()> for Option<T> {
- #[inline]
- fn to_result(&self) -> Result<T, ()> {
- match *self {
- Some(ref x) => Ok(x.clone()),
- None => Err(()),
- }
- }
-}
-
-impl<T> IntoResult<T, ()> for Option<T> {
- #[inline]
- fn into_result(self) -> Result<T, ()> {
- match self {
- Some(x) => Ok(x),
- None => Err(()),
- }
- }
-}
-
-impl<T> AsResult<T, ()> for Option<T> {
- #[inline]
- fn as_result<'a>(&'a self) -> Result<&'a T, &'a ()> {
- static UNIT: () = ();
- match *self {
- Some(ref t) => Ok(t),
- None => Err(&UNIT),
- }
- }
-}
-
-impl<T: fmt::Default> fmt::Default for Option<T> {
- #[inline]
- fn fmt(s: &Option<T>, f: &mut fmt::Formatter) {
- match *s {
- Some(ref t) => write!(f.buf, "Some({})", *t),
- None => write!(f.buf, "None")
- }
- }
-}
-
-impl<T> Default for Option<T> {
- #[inline]
- fn default() -> Option<T> { None }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// The Option Iterator
-/////////////////////////////////////////////////////////////////////////////
-
-/// An iterator that yields either one or zero elements
-#[deriving(Clone, DeepClone)]
-pub struct OptionIterator<A> {
- priv opt: Option<A>
-}
-
-impl<A> Iterator<A> for OptionIterator<A> {
- #[inline]
- fn next(&mut self) -> Option<A> {
- self.opt.take()
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- match self.opt {
- Some(_) => (1, Some(1)),
- None => (0, Some(0)),
- }
- }
-}
-
-impl<A> DoubleEndedIterator<A> for OptionIterator<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- self.opt.take()
- }
-}
-
-impl<A> ExactSize<A> for OptionIterator<A> {}
-
-/////////////////////////////////////////////////////////////////////////////
-// Tests
-/////////////////////////////////////////////////////////////////////////////
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use result::{IntoResult, ToResult};
- use result::{Ok, Err};
- use str::StrSlice;
- use util;
-
- #[test]
- fn test_get_ptr() {
- unsafe {
- let x = ~0;
- let addr_x: *int = ::cast::transmute(&*x);
- let opt = Some(x);
- let y = opt.unwrap();
- let addr_y: *int = ::cast::transmute(&*y);
- assert_eq!(addr_x, addr_y);
- }
- }
-
- #[test]
- fn test_get_str() {
- let x = ~"test";
- let addr_x = x.as_imm_buf(|buf, _len| buf);
- let opt = Some(x);
- let y = opt.unwrap();
- let addr_y = y.as_imm_buf(|buf, _len| buf);
- assert_eq!(addr_x, addr_y);
- }
-
- #[test]
- fn test_get_resource() {
- struct R {
- i: @mut int,
- }
-
- #[unsafe_destructor]
- impl ::ops::Drop for R {
- fn drop(&mut self) { *(self.i) += 1; }
- }
-
- fn R(i: @mut int) -> R {
- R {
- i: i
- }
- }
-
- let i = @mut 0;
- {
- let x = R(i);
- let opt = Some(x);
- let _y = opt.unwrap();
- }
- assert_eq!(*i, 1);
- }
-
- #[test]
- fn test_option_dance() {
- let x = Some(());
- let mut y = Some(5);
- let mut y2 = 0;
- for _x in x.iter() {
- y2 = y.take_unwrap();
- }
- assert_eq!(y2, 5);
- assert!(y.is_none());
- }
-
- #[test] #[should_fail]
- fn test_option_too_much_dance() {
- let mut y = Some(util::NonCopyable);
- let _y2 = y.take_unwrap();
- let _y3 = y.take_unwrap();
- }
-
- #[test]
- fn test_and() {
- let x: Option<int> = Some(1);
- assert_eq!(x.and(Some(2)), Some(2));
- assert_eq!(x.and(None::<int>), None);
-
- let x: Option<int> = None;
- assert_eq!(x.and(Some(2)), None);
- assert_eq!(x.and(None::<int>), None);
- }
-
- #[test]
- fn test_and_then() {
- let x: Option<int> = Some(1);
- assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
- assert_eq!(x.and_then(|_| None::<int>), None);
-
- let x: Option<int> = None;
- assert_eq!(x.and_then(|x| Some(x + 1)), None);
- assert_eq!(x.and_then(|_| None::<int>), None);
- }
-
- #[test]
- fn test_or() {
- let x: Option<int> = Some(1);
- assert_eq!(x.or(Some(2)), Some(1));
- assert_eq!(x.or(None), Some(1));
-
- let x: Option<int> = None;
- assert_eq!(x.or(Some(2)), Some(2));
- assert_eq!(x.or(None), None);
- }
-
- #[test]
- fn test_or_else() {
- let x: Option<int> = Some(1);
- assert_eq!(x.or_else(|| Some(2)), Some(1));
- assert_eq!(x.or_else(|| None), Some(1));
-
- let x: Option<int> = None;
- assert_eq!(x.or_else(|| Some(2)), Some(2));
- assert_eq!(x.or_else(|| None), None);
- }
-
- #[test]
- fn test_option_while_some() {
- let mut i = 0;
- Some(10).while_some(|j| {
- i += 1;
- if (j > 0) {
- Some(j-1)
- } else {
- None
- }
- });
- assert_eq!(i, 11);
- }
-
- #[test]
- fn test_unwrap() {
- assert_eq!(Some(1).unwrap(), 1);
- assert_eq!(Some(~"hello").unwrap(), ~"hello");
- }
-
- #[test]
- #[should_fail]
- fn test_unwrap_fail1() {
- let x: Option<int> = None;
- x.unwrap();
- }
-
- #[test]
- #[should_fail]
- fn test_unwrap_fail2() {
- let x: Option<~str> = None;
- x.unwrap();
- }
-
- #[test]
- fn test_unwrap_or() {
- let x: Option<int> = Some(1);
- assert_eq!(x.unwrap_or(2), 1);
-
- let x: Option<int> = None;
- assert_eq!(x.unwrap_or(2), 2);
- }
-
- #[test]
- fn test_unwrap_or_else() {
- let x: Option<int> = Some(1);
- assert_eq!(x.unwrap_or_else(|| 2), 1);
-
- let x: Option<int> = None;
- assert_eq!(x.unwrap_or_else(|| 2), 2);
- }
-
- #[test]
- fn test_filtered() {
- let some_stuff = Some(42);
- let modified_stuff = some_stuff.filtered(|&x| {x < 10});
- assert_eq!(some_stuff.unwrap(), 42);
- assert!(modified_stuff.is_none());
- }
-
- #[test]
- fn test_iter() {
- let val = 5;
-
- let x = Some(val);
- let mut it = x.iter();
-
- assert_eq!(it.size_hint(), (1, Some(1)));
- assert_eq!(it.next(), Some(&val));
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_mut_iter() {
- let val = 5;
- let new_val = 11;
-
- let mut x = Some(val);
- {
- let mut it = x.mut_iter();
-
- assert_eq!(it.size_hint(), (1, Some(1)));
-
- match it.next() {
- Some(interior) => {
- assert_eq!(*interior, val);
- *interior = new_val;
- }
- None => assert!(false),
- }
-
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert!(it.next().is_none());
- }
- assert_eq!(x, Some(new_val));
- }
-
- #[test]
- fn test_ord() {
- let small = Some(1.0);
- let big = Some(5.0);
- let nan = Some(0.0/0.0);
- assert!(!(nan < big));
- assert!(!(nan > big));
- assert!(small < big);
- assert!(None < big);
- assert!(big > None);
- }
-
- #[test]
- fn test_mutate() {
- let mut x = Some(3i);
- assert!(x.mutate(|i| i+1));
- assert_eq!(x, Some(4i));
- assert!(x.mutate_default(0, |i| i+1));
- assert_eq!(x, Some(5i));
- x = None;
- assert!(!x.mutate(|i| i+1));
- assert_eq!(x, None);
- assert!(!x.mutate_default(0i, |i| i+1));
- assert_eq!(x, Some(0i));
- }
-
- #[test]
- pub fn test_to_option() {
- let some: Option<int> = Some(100);
- let none: Option<int> = None;
-
- assert_eq!(some.to_option(), Some(100));
- assert_eq!(none.to_option(), None);
- }
-
- #[test]
- pub fn test_into_option() {
- let some: Option<int> = Some(100);
- let none: Option<int> = None;
-
- assert_eq!(some.into_option(), Some(100));
- assert_eq!(none.into_option(), None);
- }
-
- #[test]
- pub fn test_as_option() {
- let some: Option<int> = Some(100);
- let none: Option<int> = None;
-
- assert_eq!(some.as_option().unwrap(), &100);
- assert_eq!(none.as_option(), None);
- }
-
- #[test]
- pub fn test_to_result() {
- let some: Option<int> = Some(100);
- let none: Option<int> = None;
-
- assert_eq!(some.to_result(), Ok(100));
- assert_eq!(none.to_result(), Err(()));
- }
-
- #[test]
- pub fn test_into_result() {
- let some: Option<int> = Some(100);
- let none: Option<int> = None;
-
- assert_eq!(some.into_result(), Ok(100));
- assert_eq!(none.into_result(), Err(()));
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
- * Higher-level interfaces to libc::* functions and operating system services.
- *
- * In general these take and return rust types, use rust idioms (enums,
- * closures, vectors) rather than C idioms, and do more extensive safety
- * checks.
- *
- * This module is not meant to only contain 1:1 mappings to libc entries; any
- * os-interface code that is reasonably useful and broadly applicable can go
- * here. Including utility routines that merely build on other os code.
- *
- * We assume the general case is that users do not care, and do not want to
- * be made to care, which operating system they are on. While they may want
- * to special case various special cases -- and so we will not _hide_ the
- * facts of which OS the user is on -- they should be given the opportunity
- * to write OS-ignorant code by default.
- */
-
-#[allow(missing_doc)];
-
-#[cfg(unix)]
-use c_str::CString;
-use clone::Clone;
-use container::Container;
-use iter::range;
-use libc;
-use libc::{c_char, c_void, c_int, size_t};
-use option::{Some, None};
-use os;
-use prelude::*;
-use ptr;
-use str;
-use to_str;
-use unstable::finally::Finally;
-
-pub use os::consts::*;
-
-/// Delegates to the libc close() function, returning the same return value.
-pub fn close(fd: c_int) -> c_int {
- unsafe {
- libc::close(fd)
- }
-}
-
-pub static TMPBUF_SZ : uint = 1000u;
-static BUF_BYTES : uint = 2048u;
-
-#[cfg(unix)]
-pub fn getcwd() -> Path {
- let mut buf = [0 as libc::c_char, ..BUF_BYTES];
- buf.as_mut_buf(|buf, len| {
- unsafe {
- if libc::getcwd(buf, len as size_t).is_null() {
- fail!()
- }
-
- Path::new(CString::new(buf as *c_char, false))
- }
- })
-}
-
-#[cfg(windows)]
-pub fn getcwd() -> Path {
- use libc::DWORD;
- use libc::GetCurrentDirectoryW;
- let mut buf = [0 as u16, ..BUF_BYTES];
- buf.as_mut_buf(|buf, len| {
- unsafe {
- if libc::GetCurrentDirectoryW(len as DWORD, buf) == 0 as DWORD {
- fail!();
- }
- }
- });
- Path::new(str::from_utf16(buf))
-}
-
-#[cfg(windows)]
-pub mod win32 {
- use libc;
- use vec;
- use str;
- use option::{None, Option};
- use option;
- use os::TMPBUF_SZ;
- use libc::types::os::arch::extra::DWORD;
-
- pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD)
- -> Option<~str> {
-
- unsafe {
- let mut n = TMPBUF_SZ as DWORD;
- let mut res = None;
- let mut done = false;
- while !done {
- let mut k: DWORD = 0;
- let mut buf = vec::from_elem(n as uint, 0u16);
- buf.as_mut_buf(|b, _sz| {
- k = f(b, TMPBUF_SZ as DWORD);
- if k == (0 as DWORD) {
- done = true;
- } else if (k == n &&
- libc::GetLastError() ==
- libc::ERROR_INSUFFICIENT_BUFFER as DWORD) {
- n *= (2 as DWORD);
- } else {
- done = true;
- }
- });
- if k != 0 && done {
- let sub = buf.slice(0, k as uint);
- res = option::Some(str::from_utf16(sub));
- }
- }
- return res;
- }
- }
-
- pub fn as_utf16_p<T>(s: &str, f: |*u16| -> T) -> T {
- let mut t = s.to_utf16();
- // Null terminate before passing on.
- t.push(0u16);
- t.as_imm_buf(|buf, _len| f(buf))
- }
-}
-
-/*
-Accessing environment variables is not generally threadsafe.
-Serialize access through a global lock.
-*/
-fn with_env_lock<T>(f: || -> T) -> T {
- use unstable::mutex::{Mutex, MUTEX_INIT};
- use unstable::finally::Finally;
-
- static mut lock: Mutex = MUTEX_INIT;
-
- unsafe {
- return (|| {
- lock.lock();
- f()
- }).finally(|| lock.unlock());
- }
-}
-
-/// Returns a vector of (variable, value) pairs for all the environment
-/// variables of the current process.
-pub fn env() -> ~[(~str,~str)] {
- unsafe {
- #[cfg(windows)]
- unsafe fn get_env_pairs() -> ~[~str] {
- use c_str;
- use str::StrSlice;
-
- use libc::funcs::extra::kernel32::{
- GetEnvironmentStringsA,
- FreeEnvironmentStringsA
- };
- let ch = GetEnvironmentStringsA();
- if (ch as uint == 0) {
- fail!("os::env() failure getting env string from OS: {}",
- os::last_os_error());
- }
- let mut result = ~[];
- c_str::from_c_multistring(ch as *libc::c_char, None, |cstr| {
- result.push(cstr.as_str().unwrap().to_owned());
- });
- FreeEnvironmentStringsA(ch);
- result
- }
- #[cfg(unix)]
- unsafe fn get_env_pairs() -> ~[~str] {
- extern {
- fn rust_env_pairs() -> **libc::c_char;
- }
- let environ = rust_env_pairs();
- if (environ as uint == 0) {
- fail!("os::env() failure getting env string from OS: {}",
- os::last_os_error());
- }
- let mut result = ~[];
- ptr::array_each(environ, |e| {
- let env_pair = str::raw::from_c_str(e);
- debug!("get_env_pairs: {}", env_pair);
- result.push(env_pair);
- });
- result
- }
-
- fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
- let mut pairs = ~[];
- for p in input.iter() {
- let vs: ~[&str] = p.splitn('=', 1).collect();
- debug!("splitting: len: {}", vs.len());
- assert_eq!(vs.len(), 2);
- pairs.push((vs[0].to_owned(), vs[1].to_owned()));
- }
- pairs
- }
- with_env_lock(|| {
- let unparsed_environ = get_env_pairs();
- env_convert(unparsed_environ)
- })
- }
-}
-
-#[cfg(unix)]
-/// Fetches the environment variable `n` from the current process, returning
-/// None if the variable isn't set.
-pub fn getenv(n: &str) -> Option<~str> {
- unsafe {
- with_env_lock(|| {
- let s = n.with_c_str(|buf| libc::getenv(buf));
- if s.is_null() {
- None
- } else {
- Some(str::raw::from_c_str(s))
- }
- })
- }
-}
-
-#[cfg(windows)]
-/// Fetches the environment variable `n` from the current process, returning
-/// None if the variable isn't set.
-pub fn getenv(n: &str) -> Option<~str> {
- unsafe {
- with_env_lock(|| {
- use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
- as_utf16_p(n, |u| {
- fill_utf16_buf_and_decode(|buf, sz| {
- libc::GetEnvironmentVariableW(u, buf, sz)
- })
- })
- })
- }
-}
-
-
-#[cfg(unix)]
-/// Sets the environment variable `n` to the value `v` for the currently running
-/// process
-pub fn setenv(n: &str, v: &str) {
- unsafe {
- with_env_lock(|| {
- n.with_c_str(|nbuf| {
- v.with_c_str(|vbuf| {
- libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
- })
- })
- })
- }
-}
-
-
-#[cfg(windows)]
-/// Sets the environment variable `n` to the value `v` for the currently running
-/// process
-pub fn setenv(n: &str, v: &str) {
- unsafe {
- with_env_lock(|| {
- use os::win32::as_utf16_p;
- as_utf16_p(n, |nbuf| {
- as_utf16_p(v, |vbuf| {
- libc::SetEnvironmentVariableW(nbuf, vbuf);
- })
- })
- })
- }
-}
-
-/// Remove a variable from the environment entirely
-pub fn unsetenv(n: &str) {
- #[cfg(unix)]
- fn _unsetenv(n: &str) {
- unsafe {
- with_env_lock(|| {
- n.with_c_str(|nbuf| {
- libc::funcs::posix01::unistd::unsetenv(nbuf);
- })
- })
- }
- }
- #[cfg(windows)]
- fn _unsetenv(n: &str) {
- unsafe {
- with_env_lock(|| {
- use os::win32::as_utf16_p;
- as_utf16_p(n, |nbuf| {
- libc::SetEnvironmentVariableW(nbuf, ptr::null());
- })
- })
- }
- }
-
- _unsetenv(n);
-}
-
-pub struct Pipe {
- input: c_int,
- out: c_int
-}
-
-#[cfg(unix)]
-pub fn pipe() -> Pipe {
- unsafe {
- let mut fds = Pipe {input: 0 as c_int,
- out: 0 as c_int };
- assert_eq!(libc::pipe(&mut fds.input), (0 as c_int));
- return Pipe {input: fds.input, out: fds.out};
- }
-}
-
-#[cfg(windows)]
-pub fn pipe() -> Pipe {
- unsafe {
- // Windows pipes work subtly differently than unix pipes, and their
- // inheritance has to be handled in a different way that I do not
- // fully understand. Here we explicitly make the pipe non-inheritable,
- // which means to pass it to a subprocess they need to be duplicated
- // first, as in std::run.
- let mut fds = Pipe {input: 0 as c_int,
- out: 0 as c_int };
- let res = libc::pipe(&mut fds.input, 1024 as ::libc::c_uint,
- (libc::O_BINARY | libc::O_NOINHERIT) as c_int);
- assert_eq!(res, 0 as c_int);
- assert!((fds.input != -1 as c_int && fds.input != 0 as c_int));
- assert!((fds.out != -1 as c_int && fds.input != 0 as c_int));
- return Pipe {input: fds.input, out: fds.out};
- }
-}
-
-fn dup2(src: c_int, dst: c_int) -> c_int {
- unsafe {
- libc::dup2(src, dst)
- }
-}
-
-/// Returns the proper dll filename for the given basename of a file.
-pub fn dll_filename(base: &str) -> ~str {
- format!("{}{}{}", DLL_PREFIX, base, DLL_SUFFIX)
-}
-
-/// Optionally returns the filesystem path to the current executable which is
-/// running. If any failure occurs, None is returned.
-pub fn self_exe_path() -> Option<Path> {
-
- #[cfg(target_os = "freebsd")]
- fn load_self() -> Option<~[u8]> {
- unsafe {
- use libc::funcs::bsd44::*;
- use libc::consts::os::extra::*;
- use vec;
- let mib = ~[CTL_KERN as c_int,
- KERN_PROC as c_int,
- KERN_PROC_PATHNAME as c_int, -1 as c_int];
- let mut sz: size_t = 0;
- let err = sysctl(vec::raw::to_ptr(mib), mib.len() as ::libc::c_uint,
- ptr::mut_null(), &mut sz, ptr::null(), 0u as size_t);
- if err != 0 { return None; }
- if sz == 0 { return None; }
- let mut v: ~[u8] = vec::with_capacity(sz as uint);
- let err = v.as_mut_buf(|buf,_| {
- sysctl(vec::raw::to_ptr(mib), mib.len() as ::libc::c_uint,
- buf as *mut c_void, &mut sz, ptr::null(), 0u as size_t)
- });
- if err != 0 { return None; }
- if sz == 0 { return None; }
- vec::raw::set_len(&mut v, sz as uint - 1); // chop off trailing NUL
- Some(v)
- }
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- fn load_self() -> Option<~[u8]> {
- use std::io;
-
- match io::result(|| io::fs::readlink(&Path::new("/proc/self/exe"))) {
- Ok(Some(path)) => Some(path.as_vec().to_owned()),
- Ok(None) | Err(..) => None
- }
- }
-
- #[cfg(target_os = "macos")]
- fn load_self() -> Option<~[u8]> {
- unsafe {
- use libc::funcs::extra::_NSGetExecutablePath;
- use vec;
- let mut sz: u32 = 0;
- _NSGetExecutablePath(ptr::mut_null(), &mut sz);
- if sz == 0 { return None; }
- let mut v: ~[u8] = vec::with_capacity(sz as uint);
- let err = v.as_mut_buf(|buf, _| {
- _NSGetExecutablePath(buf as *mut i8, &mut sz)
- });
- if err != 0 { return None; }
- vec::raw::set_len(&mut v, sz as uint - 1); // chop off trailing NUL
- Some(v)
- }
- }
-
- #[cfg(windows)]
- fn load_self() -> Option<~[u8]> {
- unsafe {
- use os::win32::fill_utf16_buf_and_decode;
- fill_utf16_buf_and_decode(|buf, sz| {
- libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
- }).map(|s| s.into_bytes())
- }
- }
-
- load_self().and_then(|path| Path::new_opt(path).map(|mut p| { p.pop(); p }))
-}
-
-/**
- * Returns the path to the user's home directory, if known.
- *
- * On Unix, returns the value of the 'HOME' environment variable if it is set
- * and not equal to the empty string.
- *
- * On Windows, returns the value of the 'HOME' environment variable if it is
- * set and not equal to the empty string. Otherwise, returns the value of the
- * 'USERPROFILE' environment variable if it is set and not equal to the empty
- * string.
- *
- * Otherwise, homedir returns option::none.
- */
-pub fn homedir() -> Option<Path> {
- // FIXME (#7188): getenv needs a ~[u8] variant
- return match getenv("HOME") {
- Some(ref p) if !p.is_empty() => Path::new_opt(p.as_slice()),
- _ => secondary()
- };
-
- #[cfg(unix)]
- fn secondary() -> Option<Path> {
- None
- }
-
- #[cfg(windows)]
- fn secondary() -> Option<Path> {
- getenv("USERPROFILE").and_then(|p| {
- if !p.is_empty() {
- Path::new_opt(p)
- } else {
- None
- }
- })
- }
-}
-
-/**
- * Returns the path to a temporary directory.
- *
- * On Unix, returns the value of the 'TMPDIR' environment variable if it is
- * set and non-empty and '/tmp' otherwise.
- * On Android, there is no global temporary folder (it is usually allocated
- * per-app), hence returns '/data/tmp' which is commonly used.
- *
- * On Windows, returns the value of, in order, the 'TMP', 'TEMP',
- * 'USERPROFILE' environment variable if any are set and not the empty
- * string. Otherwise, tmpdir returns the path to the Windows directory.
- */
-pub fn tmpdir() -> Path {
- return lookup();
-
- fn getenv_nonempty(v: &str) -> Option<Path> {
- match getenv(v) {
- Some(x) =>
- if x.is_empty() {
- None
- } else {
- Path::new_opt(x)
- },
- _ => None
- }
- }
-
- #[cfg(unix)]
- fn lookup() -> Path {
- if cfg!(target_os = "android") {
- Path::new("/data/tmp")
- } else {
- getenv_nonempty("TMPDIR").unwrap_or(Path::new("/tmp"))
- }
- }
-
- #[cfg(windows)]
- fn lookup() -> Path {
- getenv_nonempty("TMP").or(
- getenv_nonempty("TEMP").or(
- getenv_nonempty("USERPROFILE").or(
- getenv_nonempty("WINDIR")))).unwrap_or(Path::new("C:\\Windows"))
- }
-}
-
-/**
- * Convert a relative path to an absolute path
- *
- * If the given path is relative, return it prepended with the current working
- * directory. If the given path is already an absolute path, return it
- * as is.
- */
-// NB: this is here rather than in path because it is a form of environment
-// querying; what it does depends on the process working directory, not just
-// the input paths.
-pub fn make_absolute(p: &Path) -> Path {
- if p.is_absolute() {
- p.clone()
- } else {
- let mut ret = getcwd();
- ret.push(p);
- ret
- }
-}
-
-/// Changes the current working directory to the specified path, returning
-/// whether the change was completed successfully or not.
-pub fn change_dir(p: &Path) -> bool {
- return chdir(p);
-
- #[cfg(windows)]
- fn chdir(p: &Path) -> bool {
- unsafe {
- use os::win32::as_utf16_p;
- return as_utf16_p(p.as_str().unwrap(), |buf| {
- libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
- });
- }
- }
-
- #[cfg(unix)]
- fn chdir(p: &Path) -> bool {
- p.with_c_str(|buf| {
- unsafe {
- libc::chdir(buf) == (0 as c_int)
- }
- })
- }
-}
-
-#[cfg(unix)]
-/// Returns the platform-specific value of errno
-pub fn errno() -> int {
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn errno_location() -> *c_int {
- #[nolink]
- extern {
- fn __error() -> *c_int;
- }
- unsafe {
- __error()
- }
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- fn errno_location() -> *c_int {
- #[nolink]
- extern {
- fn __errno_location() -> *c_int;
- }
- unsafe {
- __errno_location()
- }
- }
-
- unsafe {
- (*errno_location()) as int
- }
-}
-
-#[cfg(windows)]
-/// Returns the platform-specific value of errno
-pub fn errno() -> uint {
- use libc::types::os::arch::extra::DWORD;
-
- #[link_name = "kernel32"]
- extern "system" {
- fn GetLastError() -> DWORD;
- }
-
- unsafe {
- GetLastError() as uint
- }
-}
-
-/// Get a string representing the platform-dependent last error
-pub fn last_os_error() -> ~str {
- #[cfg(unix)]
- fn strerror() -> ~str {
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "freebsd")]
- fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
- -> c_int {
- #[nolink]
- extern {
- fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
- -> c_int;
- }
- unsafe {
- strerror_r(errnum, buf, buflen)
- }
- }
-
- // GNU libc provides a non-compliant version of strerror_r by default
- // and requires macros to instead use the POSIX compliant variant.
- // So we just use __xpg_strerror_r which is always POSIX compliant
- #[cfg(target_os = "linux")]
- fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
- #[nolink]
- extern {
- fn __xpg_strerror_r(errnum: c_int,
- buf: *mut c_char,
- buflen: size_t)
- -> c_int;
- }
- unsafe {
- __xpg_strerror_r(errnum, buf, buflen)
- }
- }
-
- let mut buf = [0 as c_char, ..TMPBUF_SZ];
-
- buf.as_mut_buf(|buf, len| {
- unsafe {
- if strerror_r(errno() as c_int, buf, len as size_t) < 0 {
- fail!("strerror_r failure");
- }
-
- str::raw::from_c_str(buf as *c_char)
- }
- })
- }
-
- #[cfg(windows)]
- fn strerror() -> ~str {
- use libc::types::os::arch::extra::DWORD;
- use libc::types::os::arch::extra::LPWSTR;
- use libc::types::os::arch::extra::LPVOID;
- use libc::types::os::arch::extra::WCHAR;
-
- #[link_name = "kernel32"]
- extern "system" {
- fn FormatMessageW(flags: DWORD,
- lpSrc: LPVOID,
- msgId: DWORD,
- langId: DWORD,
- buf: LPWSTR,
- nsize: DWORD,
- args: *c_void)
- -> DWORD;
- }
-
- static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
- static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
-
- // This value is calculated from the macro
- // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
- let langId = 0x0800 as DWORD;
- let err = errno() as DWORD;
-
- let mut buf = [0 as WCHAR, ..TMPBUF_SZ];
-
- unsafe {
- buf.as_mut_buf(|buf, len| {
- let res = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- ptr::mut_null(),
- err,
- langId,
- buf,
- len as DWORD,
- ptr::null());
- if res == 0 {
- fail!("[{}] FormatMessage failure", errno());
- }
- });
-
- str::from_utf16(buf)
- }
- }
-
- strerror()
-}
-
-/**
- * Sets the process exit code
- *
- * Sets the exit code returned by the process if all supervised tasks
- * terminate successfully (without failing). If the current root task fails
- * and is supervised by the scheduler then any user-specified exit status is
- * ignored and the process exits with the default failure status
- */
-pub fn set_exit_status(code: int) {
- use rt;
- rt::set_exit_status(code);
-}
-
-unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
- let mut args = ~[];
- for i in range(0u, argc as uint) {
- args.push(str::raw::from_c_str(*argv.offset(i as int)));
- }
- args
-}
-
-/**
- * Returns the command line arguments
- *
- * Returns a list of the command line arguments.
- */
-#[cfg(target_os = "macos")]
-fn real_args() -> ~[~str] {
- unsafe {
- let (argc, argv) = (*_NSGetArgc() as c_int,
- *_NSGetArgv() as **c_char);
- load_argc_and_argv(argc, argv)
- }
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")]
-fn real_args() -> ~[~str] {
- use rt;
-
- match rt::args::clone() {
- Some(args) => args,
- None => fail!("process arguments not initialized")
- }
-}
-
-#[cfg(windows)]
-fn real_args() -> ~[~str] {
- use vec;
-
- let mut nArgs: c_int = 0;
- let lpArgCount: *mut c_int = &mut nArgs;
- let lpCmdLine = unsafe { GetCommandLineW() };
- let szArgList = unsafe { CommandLineToArgvW(lpCmdLine, lpArgCount) };
-
- let mut args = ~[];
- for i in range(0u, nArgs as uint) {
- unsafe {
- // Determine the length of this argument.
- let ptr = *szArgList.offset(i as int);
- let mut len = 0;
- while *ptr.offset(len as int) != 0 { len += 1; }
-
- // Push it onto the list.
- args.push(vec::raw::buf_as_slice(ptr, len,
- str::from_utf16));
- }
- }
-
- unsafe {
- LocalFree(szArgList as *c_void);
- }
-
- return args;
-}
-
-type LPCWSTR = *u16;
-
-#[cfg(windows)]
-#[link_name="kernel32"]
-extern "system" {
- fn GetCommandLineW() -> LPCWSTR;
- fn LocalFree(ptr: *c_void);
-}
-
-#[cfg(windows)]
-#[link_name="shell32"]
-extern "system" {
- fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16;
-}
-
-struct OverriddenArgs {
- val: ~[~str]
-}
-
-/// Returns the arguments which this program was started with (normally passed
-/// via the command line).
-pub fn args() -> ~[~str] {
- real_args()
-}
-
-#[cfg(target_os = "macos")]
-extern {
- // These functions are in crt_externs.h.
- pub fn _NSGetArgc() -> *c_int;
- pub fn _NSGetArgv() -> ***c_char;
-}
-
-// Round up `from` to be divisible by `to`
-fn round_up(from: uint, to: uint) -> uint {
- let r = if from % to == 0 {
- from
- } else {
- from + to - (from % to)
- };
- if r == 0 {
- to
- } else {
- r
- }
-}
-
-#[cfg(unix)]
-pub fn page_size() -> uint {
- unsafe {
- libc::sysconf(libc::_SC_PAGESIZE) as uint
- }
-}
-
-#[cfg(windows)]
-pub fn page_size() -> uint {
- unsafe {
- let mut info = libc::SYSTEM_INFO::new();
- libc::GetSystemInfo(&mut info);
-
- return info.dwPageSize as uint;
- }
-}
-
-/// A memory mapped file or chunk of memory. This is a very system-specific interface to the OS's
-/// memory mapping facilities (`mmap` on POSIX, `VirtualAlloc`/`CreateFileMapping` on win32). It
-/// makes no attempt at abstracting platform differences, besides in error values returned. Consider
-/// yourself warned.
-///
-/// The memory map is released (unmapped) when the destructor is run, so don't let it leave scope by
-/// accident if you want it to stick around.
-pub struct MemoryMap {
- /// Pointer to the memory created or modified by this map.
- data: *mut u8,
- /// Number of bytes this map applies to
- len: size_t,
- /// Type of mapping
- kind: MemoryMapKind
-}
-
-/// Type of memory map
-pub enum MemoryMapKind {
- /// Memory-mapped file. On Windows, the inner pointer is a handle to the mapping, and
- /// corresponds to `CreateFileMapping`. Elsewhere, it is null.
- MapFile(*c_void),
- /// Virtual memory map. Usually used to change the permissions of a given chunk of memory.
- /// Corresponds to `VirtualAlloc` on Windows.
- MapVirtual
-}
-
-/// Options the memory map is created with
-pub enum MapOption {
- /// The memory should be readable
- MapReadable,
- /// The memory should be writable
- MapWritable,
- /// The memory should be executable
- MapExecutable,
- /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on POSIX.
- MapAddr(*c_void),
- /// Create a memory mapping for a file with a given fd.
- MapFd(c_int),
- /// When using `MapFd`, the start of the map is `uint` bytes from the start of the file.
- MapOffset(uint)
-}
-
-/// Possible errors when creating a map.
-pub enum MapError {
- /// ## The following are POSIX-specific
- ///
- /// fd was not open for reading or, if using `MapWritable`, was not open for writing.
- ErrFdNotAvail,
- /// fd was not valid
- ErrInvalidFd,
- /// Either the address given by `MapAddr` or offset given by `MapOffset` was not a multiple of
- /// `MemoryMap::granularity` (unaligned to page size).
- ErrUnaligned,
- /// With `MapFd`, the fd does not support mapping.
- ErrNoMapSupport,
- /// If using `MapAddr`, the address + `min_len` was outside of the process's address space. If
- /// using `MapFd`, the target of the fd didn't have enough resources to fulfill the request.
- ErrNoMem,
- /// Unrecognized error. The inner value is the unrecognized errno.
- ErrUnknown(libc::c_int),
- /// ## The following are win32-specific
- ///
- /// Unsupported combination of protection flags (`MapReadable`/`MapWritable`/`MapExecutable`).
- ErrUnsupProt,
- /// When using `MapFd`, `MapOffset` was given (Windows does not support this at all)
- ErrUnsupOffset,
- /// When using `MapFd`, there was already a mapping to the file.
- ErrAlreadyExists,
- /// Unrecognized error from `VirtualAlloc`. The inner value is the return value of GetLastError.
- ErrVirtualAlloc(uint),
- /// Unrecognized error from `CreateFileMapping`. The inner value is the return value of
- /// `GetLastError`.
- ErrCreateFileMappingW(uint),
- /// Unrecognized error from `MapViewOfFile`. The inner value is the return value of
- /// `GetLastError`.
- ErrMapViewOfFile(uint)
-}
-
-impl to_str::ToStr for MapError {
- fn to_str(&self) -> ~str {
- match *self {
- ErrFdNotAvail => ~"fd not available for reading or writing",
- ErrInvalidFd => ~"Invalid fd",
- ErrUnaligned => ~"Unaligned address, invalid flags, \
- negative length or unaligned offset",
- ErrNoMapSupport=> ~"File doesn't support mapping",
- ErrNoMem => ~"Invalid address, or not enough available memory",
- ErrUnknown(code) => format!("Unknown error={}", code),
- ErrUnsupProt => ~"Protection mode unsupported",
- ErrUnsupOffset => ~"Offset in virtual memory mode is unsupported",
- ErrAlreadyExists => ~"File mapping for specified file already exists",
- ErrVirtualAlloc(code) => format!("VirtualAlloc failure={}", code),
- ErrCreateFileMappingW(code) => format!("CreateFileMappingW failure={}", code),
- ErrMapViewOfFile(code) => format!("MapViewOfFile failure={}", code)
- }
- }
-}
-
-#[cfg(unix)]
-impl MemoryMap {
- /// Create a new mapping with the given `options`, at least `min_len` bytes long.
- pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
- use libc::off_t;
-
- let mut addr: *c_void = ptr::null();
- let mut prot: c_int = 0;
- let mut flags: c_int = libc::MAP_PRIVATE;
- let mut fd: c_int = -1;
- let mut offset: off_t = 0;
- let len = round_up(min_len, page_size()) as size_t;
-
- for &o in options.iter() {
- match o {
- MapReadable => { prot |= libc::PROT_READ; },
- MapWritable => { prot |= libc::PROT_WRITE; },
- MapExecutable => { prot |= libc::PROT_EXEC; },
- MapAddr(addr_) => {
- flags |= libc::MAP_FIXED;
- addr = addr_;
- },
- MapFd(fd_) => {
- flags |= libc::MAP_FILE;
- fd = fd_;
- },
- MapOffset(offset_) => { offset = offset_ as off_t; }
- }
- }
- if fd == -1 { flags |= libc::MAP_ANON; }
-
- let r = unsafe {
- libc::mmap(addr, len, prot, flags, fd, offset)
- };
- if r.equiv(&libc::MAP_FAILED) {
- Err(match errno() as c_int {
- libc::EACCES => ErrFdNotAvail,
- libc::EBADF => ErrInvalidFd,
- libc::EINVAL => ErrUnaligned,
- libc::ENODEV => ErrNoMapSupport,
- libc::ENOMEM => ErrNoMem,
- code => ErrUnknown(code)
- })
- } else {
- Ok(MemoryMap {
- data: r as *mut u8,
- len: len,
- kind: if fd == -1 {
- MapVirtual
- } else {
- MapFile(ptr::null())
- }
- })
- }
- }
-
- /// Granularity that the offset or address must be for `MapOffset` and `MapAddr` respectively.
- pub fn granularity() -> uint {
- page_size()
- }
-}
-
-#[cfg(unix)]
-impl Drop for MemoryMap {
- /// Unmap the mapping. Fails the task if `munmap` fails.
- fn drop(&mut self) {
- unsafe {
- match libc::munmap(self.data as *c_void, self.len) {
- 0 => (),
- -1 => match errno() as c_int {
- libc::EINVAL => error!("invalid addr or len"),
- e => error!("unknown errno={}", e)
- },
- r => error!("Unexpected result {}", r)
- }
- }
- }
-}
-
-#[cfg(windows)]
-impl MemoryMap {
- /// Create a new mapping with the given `options`, at least `min_len` bytes long.
- pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
- use libc::types::os::arch::extra::{LPVOID, DWORD, SIZE_T, HANDLE};
-
- let mut lpAddress: LPVOID = ptr::mut_null();
- let mut readable = false;
- let mut writable = false;
- let mut executable = false;
- let mut fd: c_int = -1;
- let mut offset: uint = 0;
- let len = round_up(min_len, page_size()) as SIZE_T;
-
- for &o in options.iter() {
- match o {
- MapReadable => { readable = true; },
- MapWritable => { writable = true; },
- MapExecutable => { executable = true; }
- MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
- MapFd(fd_) => { fd = fd_; },
- MapOffset(offset_) => { offset = offset_; }
- }
- }
-
- let flProtect = match (executable, readable, writable) {
- (false, false, false) if fd == -1 => libc::PAGE_NOACCESS,
- (false, true, false) => libc::PAGE_READONLY,
- (false, true, true) => libc::PAGE_READWRITE,
- (true, false, false) if fd == -1 => libc::PAGE_EXECUTE,
- (true, true, false) => libc::PAGE_EXECUTE_READ,
- (true, true, true) => libc::PAGE_EXECUTE_READWRITE,
- _ => return Err(ErrUnsupProt)
- };
-
- if fd == -1 {
- if offset != 0 {
- return Err(ErrUnsupOffset);
- }
- let r = unsafe {
- libc::VirtualAlloc(lpAddress,
- len,
- libc::MEM_COMMIT | libc::MEM_RESERVE,
- flProtect)
- };
- match r as uint {
- 0 => Err(ErrVirtualAlloc(errno())),
- _ => Ok(MemoryMap {
- data: r as *mut u8,
- len: len,
- kind: MapVirtual
- })
- }
- } else {
- let dwDesiredAccess = match (executable, readable, writable) {
- (false, true, false) => libc::FILE_MAP_READ,
- (false, true, true) => libc::FILE_MAP_WRITE,
- (true, true, false) => libc::FILE_MAP_READ | libc::FILE_MAP_EXECUTE,
- (true, true, true) => libc::FILE_MAP_WRITE | libc::FILE_MAP_EXECUTE,
- _ => return Err(ErrUnsupProt) // Actually, because of the check above,
- // we should never get here.
- };
- unsafe {
- let hFile = libc::get_osfhandle(fd) as HANDLE;
- let mapping = libc::CreateFileMappingW(hFile,
- ptr::mut_null(),
- flProtect,
- 0,
- 0,
- ptr::null());
- if mapping == ptr::mut_null() {
- return Err(ErrCreateFileMappingW(errno()));
- }
- if errno() as c_int == libc::ERROR_ALREADY_EXISTS {
- return Err(ErrAlreadyExists);
- }
- let r = libc::MapViewOfFile(mapping,
- dwDesiredAccess,
- ((len as u64) >> 32) as DWORD,
- (offset & 0xffff_ffff) as DWORD,
- 0);
- match r as uint {
- 0 => Err(ErrMapViewOfFile(errno())),
- _ => Ok(MemoryMap {
- data: r as *mut u8,
- len: len,
- kind: MapFile(mapping as *c_void)
- })
- }
- }
- }
- }
-
- /// Granularity of MapAddr() and MapOffset() parameter values.
- /// This may be greater than the value returned by page_size().
- pub fn granularity() -> uint {
- unsafe {
- let mut info = libc::SYSTEM_INFO::new();
- libc::GetSystemInfo(&mut info);
-
- return info.dwAllocationGranularity as uint;
- }
- }
-}
-
-#[cfg(windows)]
-impl Drop for MemoryMap {
- /// Unmap the mapping. Fails the task if any of `VirtualFree`, `UnmapViewOfFile`, or
- /// `CloseHandle` fail.
- fn drop(&mut self) {
- use libc::types::os::arch::extra::{LPCVOID, HANDLE};
- use libc::consts::os::extra::FALSE;
-
- unsafe {
- match self.kind {
- MapVirtual => {
- if libc::VirtualFree(self.data as *mut c_void,
- self.len,
- libc::MEM_RELEASE) == FALSE {
- error!("VirtualFree failed: {}", errno());
- }
- },
- MapFile(mapping) => {
- if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE {
- error!("UnmapViewOfFile failed: {}", errno());
- }
- if libc::CloseHandle(mapping as HANDLE) == FALSE {
- error!("CloseHandle failed: {}", errno());
- }
- }
- }
- }
- }
-}
-
-pub mod consts {
-
- #[cfg(unix)]
- pub use os::consts::unix::*;
-
- #[cfg(windows)]
- pub use os::consts::windows::*;
-
- #[cfg(target_os = "macos")]
- pub use os::consts::macos::*;
-
- #[cfg(target_os = "freebsd")]
- pub use os::consts::freebsd::*;
-
- #[cfg(target_os = "linux")]
- pub use os::consts::linux::*;
-
- #[cfg(target_os = "android")]
- pub use os::consts::android::*;
-
- #[cfg(target_os = "win32")]
- pub use os::consts::win32::*;
-
- #[cfg(target_arch = "x86")]
- pub use os::consts::x86::*;
-
- #[cfg(target_arch = "x86_64")]
- pub use os::consts::x86_64::*;
-
- #[cfg(target_arch = "arm")]
- pub use os::consts::arm::*;
-
- #[cfg(target_arch = "mips")]
- pub use os::consts::mips::*;
-
- pub mod unix {
- pub static FAMILY: &'static str = "unix";
- }
-
- pub mod windows {
- pub static FAMILY: &'static str = "windows";
- }
-
- pub mod macos {
- pub static SYSNAME: &'static str = "macos";
- pub static DLL_PREFIX: &'static str = "lib";
- pub static DLL_SUFFIX: &'static str = ".dylib";
- pub static DLL_EXTENSION: &'static str = "dylib";
- pub static EXE_SUFFIX: &'static str = "";
- pub static EXE_EXTENSION: &'static str = "";
- }
-
- pub mod freebsd {
- pub static SYSNAME: &'static str = "freebsd";
- pub static DLL_PREFIX: &'static str = "lib";
- pub static DLL_SUFFIX: &'static str = ".so";
- pub static DLL_EXTENSION: &'static str = "so";
- pub static EXE_SUFFIX: &'static str = "";
- pub static EXE_EXTENSION: &'static str = "";
- }
-
- pub mod linux {
- pub static SYSNAME: &'static str = "linux";
- pub static DLL_PREFIX: &'static str = "lib";
- pub static DLL_SUFFIX: &'static str = ".so";
- pub static DLL_EXTENSION: &'static str = "so";
- pub static EXE_SUFFIX: &'static str = "";
- pub static EXE_EXTENSION: &'static str = "";
- }
-
- pub mod android {
- pub static SYSNAME: &'static str = "android";
- pub static DLL_PREFIX: &'static str = "lib";
- pub static DLL_SUFFIX: &'static str = ".so";
- pub static DLL_EXTENSION: &'static str = "so";
- pub static EXE_SUFFIX: &'static str = "";
- pub static EXE_EXTENSION: &'static str = "";
- }
-
- pub mod win32 {
- pub static SYSNAME: &'static str = "win32";
- pub static DLL_PREFIX: &'static str = "";
- pub static DLL_SUFFIX: &'static str = ".dll";
- pub static DLL_EXTENSION: &'static str = "dll";
- pub static EXE_SUFFIX: &'static str = ".exe";
- pub static EXE_EXTENSION: &'static str = "exe";
- }
-
-
- pub mod x86 {
- pub static ARCH: &'static str = "x86";
- }
- pub mod x86_64 {
- pub static ARCH: &'static str = "x86_64";
- }
- pub mod arm {
- pub static ARCH: &'static str = "arm";
- }
- pub mod mips {
- pub static ARCH: &'static str = "mips";
- }
-}
-
-#[cfg(test)]
-mod tests {
- use c_str::ToCStr;
- use option::Some;
- use option;
- use os::{env, getcwd, getenv, make_absolute, args};
- use os::{setenv, unsetenv};
- use os;
- use path::Path;
- use rand::Rng;
- use rand;
- use str::StrSlice;
-
-
- #[test]
- pub fn last_os_error() {
- debug!("{}", os::last_os_error());
- }
-
- #[test]
- pub fn test_args() {
- let a = args();
- assert!(a.len() >= 1);
- }
-
- fn make_rand_name() -> ~str {
- let mut rng = rand::rng();
- let n = ~"TEST" + rng.gen_ascii_str(10u);
- assert!(getenv(n).is_none());
- n
- }
-
- #[test]
- fn test_setenv() {
- let n = make_rand_name();
- setenv(n, "VALUE");
- assert_eq!(getenv(n), option::Some(~"VALUE"));
- }
-
- #[test]
- fn test_unsetenv() {
- let n = make_rand_name();
- setenv(n, "VALUE");
- unsetenv(n);
- assert_eq!(getenv(n), option::None);
- }
-
- #[test]
- #[ignore]
- fn test_setenv_overwrite() {
- let n = make_rand_name();
- setenv(n, "1");
- setenv(n, "2");
- assert_eq!(getenv(n), option::Some(~"2"));
- setenv(n, "");
- assert_eq!(getenv(n), option::Some(~""));
- }
-
- // Windows GetEnvironmentVariable requires some extra work to make sure
- // the buffer the variable is copied into is the right size
- #[test]
- #[ignore]
- fn test_getenv_big() {
- let mut s = ~"";
- let mut i = 0;
- while i < 100 {
- s = s + "aaaaaaaaaa";
- i += 1;
- }
- let n = make_rand_name();
- setenv(n, s);
- debug!("{}", s.clone());
- assert_eq!(getenv(n), option::Some(s));
- }
-
- #[test]
- fn test_self_exe_path() {
- let path = os::self_exe_path();
- assert!(path.is_some());
- let path = path.unwrap();
- debug!("{:?}", path.clone());
-
- // Hard to test this function
- assert!(path.is_absolute());
- }
-
- #[test]
- #[ignore]
- fn test_env_getenv() {
- let e = env();
- assert!(e.len() > 0u);
- for p in e.iter() {
- let (n, v) = (*p).clone();
- debug!("{:?}", n.clone());
- let v2 = getenv(n);
- // MingW seems to set some funky environment variables like
- // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
- // from env() but not visible from getenv().
- assert!(v2.is_none() || v2 == option::Some(v));
- }
- }
-
- #[test]
- fn test_env_setenv() {
- let n = make_rand_name();
-
- let mut e = env();
- setenv(n, "VALUE");
- assert!(!e.contains(&(n.clone(), ~"VALUE")));
-
- e = env();
- assert!(e.contains(&(n, ~"VALUE")));
- }
-
- #[test]
- fn test() {
- assert!((!Path::new("test-path").is_absolute()));
-
- let cwd = getcwd();
- debug!("Current working directory: {}", cwd.display());
-
- debug!("{:?}", make_absolute(&Path::new("test-path")));
- debug!("{:?}", make_absolute(&Path::new("/usr/bin")));
- }
-
- #[test]
- #[cfg(unix)]
- fn homedir() {
- let oldhome = getenv("HOME");
-
- setenv("HOME", "/home/MountainView");
- assert_eq!(os::homedir(), Some(Path::new("/home/MountainView")));
-
- setenv("HOME", "");
- assert!(os::homedir().is_none());
-
- for s in oldhome.iter() { setenv("HOME", *s) }
- }
-
- #[test]
- #[cfg(windows)]
- fn homedir() {
-
- let oldhome = getenv("HOME");
- let olduserprofile = getenv("USERPROFILE");
-
- setenv("HOME", "");
- setenv("USERPROFILE", "");
-
- assert!(os::homedir().is_none());
-
- setenv("HOME", "/home/MountainView");
- assert_eq!(os::homedir(), Some(Path::new("/home/MountainView")));
-
- setenv("HOME", "");
-
- setenv("USERPROFILE", "/home/MountainView");
- assert_eq!(os::homedir(), Some(Path::new("/home/MountainView")));
-
- setenv("HOME", "/home/MountainView");
- setenv("USERPROFILE", "/home/PaloAlto");
- assert_eq!(os::homedir(), Some(Path::new("/home/MountainView")));
-
- for s in oldhome.iter() { setenv("HOME", *s) }
- for s in olduserprofile.iter() { setenv("USERPROFILE", *s) }
- }
-
- #[test]
- fn memory_map_rw() {
- use result::{Ok, Err};
-
- let chunk = match os::MemoryMap::new(16, [
- os::MapReadable,
- os::MapWritable
- ]) {
- Ok(chunk) => chunk,
- Err(msg) => fail!(msg.to_str())
- };
- assert!(chunk.len >= 16);
-
- unsafe {
- *chunk.data = 0xBE;
- assert!(*chunk.data == 0xBE);
- }
- }
-
- #[test]
- fn memory_map_file() {
- use result::{Ok, Err};
- use os::*;
- use libc::*;
- use io;
- use io::fs;
-
- #[cfg(unix)]
- fn lseek_(fd: c_int, size: uint) {
- unsafe {
- assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t);
- }
- }
- #[cfg(windows)]
- fn lseek_(fd: c_int, size: uint) {
- unsafe {
- assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long);
- }
- }
-
- let mut path = tmpdir();
- path.push("mmap_file.tmp");
- let size = MemoryMap::granularity() * 2;
-
- let fd = unsafe {
- let fd = path.with_c_str(|path| {
- open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
- });
- lseek_(fd, size);
- "x".with_c_str(|x| assert!(write(fd, x as *c_void, 1) == 1));
- fd
- };
- let chunk = match MemoryMap::new(size / 2, [
- MapReadable,
- MapWritable,
- MapFd(fd),
- MapOffset(size / 2)
- ]) {
- Ok(chunk) => chunk,
- Err(msg) => fail!(msg.to_str())
- };
- assert!(chunk.len > 0);
-
- unsafe {
- *chunk.data = 0xbe;
- assert!(*chunk.data == 0xbe);
- close(fd);
- }
- io::ignore_io_error(|| fs::unlink(&path));
- }
-
- // More recursive_mkdir tests are in extra::tempfile
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations on unique pointer types
-
-#[cfg(not(test))] use cmp::*;
-
-#[cfg(not(test))]
-impl<T:Eq> Eq for ~T {
- #[inline]
- fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) }
- #[inline]
- fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) }
-}
-
-#[cfg(not(test))]
-impl<T:Ord> Ord for ~T {
- #[inline]
- fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) }
- #[inline]
- fn le(&self, other: &~T) -> bool { *(*self) <= *(*other) }
- #[inline]
- fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) }
- #[inline]
- fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) }
-}
-
-#[cfg(not(test))]
-impl<T: TotalOrd> TotalOrd for ~T {
- #[inline]
- fn cmp(&self, other: &~T) -> Ordering { (**self).cmp(*other) }
-}
-
-#[cfg(not(test))]
-impl<T: TotalEq> TotalEq for ~T {
- #[inline]
- fn equals(&self, other: &~T) -> bool { (**self).equals(*other) }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Cross-platform path support
-
-This module implements support for two flavors of paths. `PosixPath` represents
-a path on any unix-like system, whereas `WindowsPath` represents a path on
-Windows. This module also exposes a typedef `Path` which is equal to the
-appropriate platform-specific path variant.
-
-Both `PosixPath` and `WindowsPath` implement a trait `GenericPath`, which
-contains the set of methods that behave the same for both paths. They each also
-implement some methods that could not be expressed in `GenericPath`, yet behave
-identically for both path flavors, such as `.components()`.
-
-The three main design goals of this module are 1) to avoid unnecessary
-allocation, 2) to behave the same regardless of which flavor of path is being
-used, and 3) to support paths that cannot be represented in UTF-8 (as Linux has
-no restriction on paths beyond disallowing NUL).
-
-## Usage
-
-Usage of this module is fairly straightforward. Unless writing platform-specific
-code, `Path` should be used to refer to the platform-native path.
-
-Creation of a path is typically done with either `Path::new(some_str)` or
-`Path::new(some_vec)`. This path can be modified with `.push()` and
-`.pop()` (and other setters). The resulting Path can either be passed to another
-API that expects a path, or can be turned into a &[u8] with `.as_vec()` or a
-Option<&str> with `.as_str()`. Similarly, attributes of the path can be queried
-with methods such as `.filename()`. There are also methods that return a new
-path instead of modifying the receiver, such as `.join()` or `.dir_path()`.
-
-Paths are always kept in normalized form. This means that creating the path
-`Path::new("a/b/../c")` will return the path `a/c`. Similarly any attempt
-to mutate the path will always leave it in normalized form.
-
-When rendering a path to some form of output, there is a method `.display()`
-which is compatible with the `format!()` parameter `{}`. This will render the
-path as a string, replacing all non-utf8 sequences with the Replacement
-Character (U+FFFD). As such it is not suitable for passing to any API that
-actually operates on the path; it is only intended for display.
-
-## Example
-
-```rust
-let mut path = Path::new("/tmp/path");
-debug!("path: {}", path.display());
-path.set_filename("foo");
-path.push("bar");
-debug!("new path: {}", path.display());
-let b = std::os::path_exists(&path);
-debug!("path exists: {}", b);
-```
-
-*/
-
-use container::Container;
-use c_str::CString;
-use clone::Clone;
-use fmt;
-use iter::Iterator;
-use option::{Option, None, Some};
-use str;
-use str::{OwnedStr, Str, StrSlice};
-use to_str::ToStr;
-use vec;
-use vec::{CopyableVector, OwnedCopyableVector, OwnedVector, Vector};
-use vec::{ImmutableEqVector, ImmutableVector};
-
-/// Typedef for POSIX file paths.
-/// See `posix::Path` for more info.
-pub use PosixPath = self::posix::Path;
-
-/// Typedef for Windows file paths.
-/// See `windows::Path` for more info.
-pub use WindowsPath = self::windows::Path;
-
-/// Typedef for the platform-native path type
-#[cfg(unix)]
-pub use Path = self::posix::Path;
-/// Typedef for the platform-native path type
-#[cfg(windows)]
-pub use Path = self::windows::Path;
-
-/// Typedef for the platform-native component iterator
-#[cfg(unix)]
-pub use ComponentIter = self::posix::ComponentIter;
-/// Typedef for the platform-native reverse component iterator
-#[cfg(unix)]
-pub use RevComponentIter = self::posix::RevComponentIter;
-/// Typedef for the platform-native component iterator
-#[cfg(windows)]
-pub use ComponentIter = self::windows::ComponentIter;
-/// Typedef for the platform-native reverse component iterator
-#[cfg(windows)]
-pub use RevComponentIter = self::windows::RevComponentIter;
-
-/// Typedef for the platform-native str component iterator
-#[cfg(unix)]
-pub use StrComponentIter = self::posix::StrComponentIter;
-/// Typedef for the platform-native reverse str component iterator
-#[cfg(unix)]
-pub use RevStrComponentIter = self::posix::RevStrComponentIter;
-/// Typedef for the platform-native str component iterator
-#[cfg(windows)]
-pub use StrComponentIter = self::windows::StrComponentIter;
-/// Typedef for the platform-native reverse str component iterator
-#[cfg(windows)]
-pub use RevStrComponentIter = self::windows::RevStrComponentIter;
-
-/// Typedef for the platform-native separator char func
-#[cfg(unix)]
-pub use is_sep = self::posix::is_sep;
-/// Typedef for the platform-native separator char func
-#[cfg(windows)]
-pub use is_sep = self::windows::is_sep;
-/// Typedef for the platform-native separator byte func
-#[cfg(unix)]
-pub use is_sep_byte = self::posix::is_sep_byte;
-/// Typedef for the platform-native separator byte func
-#[cfg(windows)]
-pub use is_sep_byte = self::windows::is_sep_byte;
-
-pub mod posix;
-pub mod windows;
-
-// Condition that is raised when a NUL is found in a byte vector given to a Path function
-condition! {
- // this should be a &[u8] but there's a lifetime issue
- null_byte: ~[u8] -> ~[u8];
-}
-
-/// A trait that represents the generic operations available on paths
-pub trait GenericPath: Clone + GenericPathUnsafe {
- /// Creates a new Path from a byte vector or string.
- /// The resulting Path will always be normalized.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the path contains a NUL.
- ///
- /// See individual Path impls for additional restrictions.
- #[inline]
- fn new<T: BytesContainer>(path: T) -> Self {
- if contains_nul(path.container_as_bytes()) {
- let path = self::null_byte::cond.raise(path.container_into_owned_bytes());
- assert!(!contains_nul(path));
- unsafe { GenericPathUnsafe::new_unchecked(path) }
- } else {
- unsafe { GenericPathUnsafe::new_unchecked(path) }
- }
- }
-
- /// Creates a new Path from a byte vector or string, if possible.
- /// The resulting Path will always be normalized.
- #[inline]
- fn new_opt<T: BytesContainer>(path: T) -> Option<Self> {
- if contains_nul(path.container_as_bytes()) {
- None
- } else {
- Some(unsafe { GenericPathUnsafe::new_unchecked(path) })
- }
- }
-
- /// Returns the path as a string, if possible.
- /// If the path is not representable in utf-8, this returns None.
- #[inline]
- fn as_str<'a>(&'a self) -> Option<&'a str> {
- str::from_utf8_slice_opt(self.as_vec())
- }
-
- /// Returns the path as a byte vector
- fn as_vec<'a>(&'a self) -> &'a [u8];
-
- /// Converts the Path into an owned byte vector
- fn into_vec(self) -> ~[u8];
-
- /// Returns an object that implements `fmt::Default` for printing paths
- ///
- /// This will print the equivalent of `to_display_str()` when used with a {} format parameter.
- fn display<'a>(&'a self) -> Display<'a, Self> {
- Display{ path: self, filename: false }
- }
-
- /// Returns an object that implements `fmt::Default` for printing filenames
- ///
- /// This will print the equivalent of `to_filename_display_str()` when used with a {}
- /// format parameter. If there is no filename, nothing will be printed.
- fn filename_display<'a>(&'a self) -> Display<'a, Self> {
- Display{ path: self, filename: true }
- }
-
- /// Returns the directory component of `self`, as a byte vector (with no trailing separator).
- /// If `self` has no directory component, returns ['.'].
- fn dirname<'a>(&'a self) -> &'a [u8];
- /// Returns the directory component of `self`, as a string, if possible.
- /// See `dirname` for details.
- #[inline]
- fn dirname_str<'a>(&'a self) -> Option<&'a str> {
- str::from_utf8_slice_opt(self.dirname())
- }
- /// Returns the file component of `self`, as a byte vector.
- /// If `self` represents the root of the file hierarchy, returns None.
- /// If `self` is "." or "..", returns None.
- fn filename<'a>(&'a self) -> Option<&'a [u8]>;
- /// Returns the file component of `self`, as a string, if possible.
- /// See `filename` for details.
- #[inline]
- fn filename_str<'a>(&'a self) -> Option<&'a str> {
- self.filename().and_then(str::from_utf8_slice_opt)
- }
- /// Returns the stem of the filename of `self`, as a byte vector.
- /// The stem is the portion of the filename just before the last '.'.
- /// If there is no '.', the entire filename is returned.
- fn filestem<'a>(&'a self) -> Option<&'a [u8]> {
- match self.filename() {
- None => None,
- Some(name) => Some({
- let dot = '.' as u8;
- match name.rposition_elem(&dot) {
- None | Some(0) => name,
- Some(1) if name == bytes!("..") => name,
- Some(pos) => name.slice_to(pos)
- }
- })
- }
- }
- /// Returns the stem of the filename of `self`, as a string, if possible.
- /// See `filestem` for details.
- #[inline]
- fn filestem_str<'a>(&'a self) -> Option<&'a str> {
- self.filestem().and_then(str::from_utf8_slice_opt)
- }
- /// Returns the extension of the filename of `self`, as an optional byte vector.
- /// The extension is the portion of the filename just after the last '.'.
- /// If there is no extension, None is returned.
- /// If the filename ends in '.', the empty vector is returned.
- fn extension<'a>(&'a self) -> Option<&'a [u8]> {
- match self.filename() {
- None => None,
- Some(name) => {
- let dot = '.' as u8;
- match name.rposition_elem(&dot) {
- None | Some(0) => None,
- Some(1) if name == bytes!("..") => None,
- Some(pos) => Some(name.slice_from(pos+1))
- }
- }
- }
- }
- /// Returns the extension of the filename of `self`, as a string, if possible.
- /// See `extension` for details.
- #[inline]
- fn extension_str<'a>(&'a self) -> Option<&'a str> {
- self.extension().and_then(str::from_utf8_slice_opt)
- }
-
- /// Replaces the filename portion of the path with the given byte vector or string.
- /// If the replacement name is [], this is equivalent to popping the path.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the filename contains a NUL.
- #[inline]
- fn set_filename<T: BytesContainer>(&mut self, filename: T) {
- if contains_nul(filename.container_as_bytes()) {
- let filename = self::null_byte::cond.raise(filename.container_into_owned_bytes());
- assert!(!contains_nul(filename));
- unsafe { self.set_filename_unchecked(filename) }
- } else {
- unsafe { self.set_filename_unchecked(filename) }
- }
- }
- /// Replaces the extension with the given byte vector or string.
- /// If there is no extension in `self`, this adds one.
- /// If the argument is [] or "", this removes the extension.
- /// If `self` has no filename, this is a no-op.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the extension contains a NUL.
- fn set_extension<T: BytesContainer>(&mut self, extension: T) {
- // borrowck causes problems here too
- let val = {
- match self.filename() {
- None => None,
- Some(name) => {
- let dot = '.' as u8;
- match name.rposition_elem(&dot) {
- None | Some(0) => {
- if extension.container_as_bytes().is_empty() {
- None
- } else {
- let mut v;
- if contains_nul(extension.container_as_bytes()) {
- let ext = extension.container_into_owned_bytes();
- let extension = self::null_byte::cond.raise(ext);
- assert!(!contains_nul(extension));
- v = vec::with_capacity(name.len() + extension.len() + 1);
- v.push_all(name);
- v.push(dot);
- v.push_all(extension);
- } else {
- let extension = extension.container_as_bytes();
- v = vec::with_capacity(name.len() + extension.len() + 1);
- v.push_all(name);
- v.push(dot);
- v.push_all(extension);
- }
- Some(v)
- }
- }
- Some(idx) => {
- if extension.container_as_bytes().is_empty() {
- Some(name.slice_to(idx).to_owned())
- } else {
- let mut v;
- if contains_nul(extension.container_as_bytes()) {
- let ext = extension.container_into_owned_bytes();
- let extension = self::null_byte::cond.raise(ext);
- assert!(!contains_nul(extension));
- v = vec::with_capacity(idx + extension.len() + 1);
- v.push_all(name.slice_to(idx+1));
- v.push_all(extension);
- } else {
- let extension = extension.container_as_bytes();
- v = vec::with_capacity(idx + extension.len() + 1);
- v.push_all(name.slice_to(idx+1));
- v.push_all(extension);
- }
- Some(v)
- }
- }
- }
- }
- }
- };
- match val {
- None => (),
- Some(v) => unsafe { self.set_filename_unchecked(v) }
- }
- }
-
- /// Returns a new Path constructed by replacing the filename with the given
- /// byte vector or string.
- /// See `set_filename` for details.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the filename contains a NUL.
- #[inline]
- fn with_filename<T: BytesContainer>(&self, filename: T) -> Self {
- let mut p = self.clone();
- p.set_filename(filename);
- p
- }
- /// Returns a new Path constructed by setting the extension to the given
- /// byte vector or string.
- /// See `set_extension` for details.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the extension contains a NUL.
- #[inline]
- fn with_extension<T: BytesContainer>(&self, extension: T) -> Self {
- let mut p = self.clone();
- p.set_extension(extension);
- p
- }
-
- /// Returns the directory component of `self`, as a Path.
- /// If `self` represents the root of the filesystem hierarchy, returns `self`.
- fn dir_path(&self) -> Self {
- // self.dirname() returns a NUL-free vector
- unsafe { GenericPathUnsafe::new_unchecked(self.dirname()) }
- }
-
- /// Returns a Path that represents the filesystem root that `self` is rooted in.
- ///
- /// If `self` is not absolute, or vol-relative in the case of Windows, this returns None.
- fn root_path(&self) -> Option<Self>;
-
- /// Pushes a path (as a byte vector or string) onto `self`.
- /// If the argument represents an absolute path, it replaces `self`.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the path contains a NUL.
- #[inline]
- fn push<T: BytesContainer>(&mut self, path: T) {
- if contains_nul(path.container_as_bytes()) {
- let path = self::null_byte::cond.raise(path.container_into_owned_bytes());
- assert!(!contains_nul(path));
- unsafe { self.push_unchecked(path) }
- } else {
- unsafe { self.push_unchecked(path) }
- }
- }
- /// Pushes multiple paths (as byte vectors or strings) onto `self`.
- /// See `push` for details.
- #[inline]
- fn push_many<T: BytesContainer>(&mut self, paths: &[T]) {
- let t: Option<T> = None;
- if BytesContainer::is_str(t) {
- for p in paths.iter() {
- self.push(p.container_as_str())
- }
- } else {
- for p in paths.iter() {
- self.push(p.container_as_bytes())
- }
- }
- }
- /// Removes the last path component from the receiver.
- /// Returns `true` if the receiver was modified, or `false` if it already
- /// represented the root of the file hierarchy.
- fn pop(&mut self) -> bool;
-
- /// Returns a new Path constructed by joining `self` with the given path
- /// (as a byte vector or string).
- /// If the given path is absolute, the new Path will represent just that.
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the path contains a NUL.
- #[inline]
- fn join<T: BytesContainer>(&self, path: T) -> Self {
- let mut p = self.clone();
- p.push(path);
- p
- }
- /// Returns a new Path constructed by joining `self` with the given paths
- /// (as byte vectors or strings).
- /// See `join` for details.
- #[inline]
- fn join_many<T: BytesContainer>(&self, paths: &[T]) -> Self {
- let mut p = self.clone();
- p.push_many(paths);
- p
- }
-
- /// Returns whether `self` represents an absolute path.
- /// An absolute path is defined as one that, when joined to another path, will
- /// yield back the same absolute path.
- fn is_absolute(&self) -> bool;
-
- /// Returns whether `self` represents a relative path.
- /// Typically this is the inverse of `is_absolute`.
- /// But for Windows paths, it also means the path is not volume-relative or
- /// relative to the current working directory.
- fn is_relative(&self) -> bool {
- !self.is_absolute()
- }
-
- /// Returns whether `self` is equal to, or is an ancestor of, the given path.
- /// If both paths are relative, they are compared as though they are relative
- /// to the same parent path.
- fn is_ancestor_of(&self, other: &Self) -> bool;
-
- /// Returns the Path that, were it joined to `base`, would yield `self`.
- /// If no such path exists, None is returned.
- /// If `self` is absolute and `base` is relative, or on Windows if both
- /// paths refer to separate drives, an absolute path is returned.
- fn path_relative_from(&self, base: &Self) -> Option<Self>;
-
- /// Returns whether the relative path `child` is a suffix of `self`.
- fn ends_with_path(&self, child: &Self) -> bool;
-}
-
-/// A trait that represents something bytes-like (e.g. a &[u8] or a &str)
-pub trait BytesContainer {
- /// Returns a &[u8] representing the receiver
- fn container_as_bytes<'a>(&'a self) -> &'a [u8];
- /// Consumes the receiver and converts it into ~[u8]
- #[inline]
- fn container_into_owned_bytes(self) -> ~[u8] {
- self.container_as_bytes().to_owned()
- }
- /// Returns the receiver interpreted as a utf-8 string
- ///
- /// # Failure
- ///
- /// Raises `str::null_byte` if not utf-8
- #[inline]
- fn container_as_str<'a>(&'a self) -> &'a str {
- str::from_utf8_slice(self.container_as_bytes())
- }
- /// Returns the receiver interpreted as a utf-8 string, if possible
- #[inline]
- fn container_as_str_opt<'a>(&'a self) -> Option<&'a str> {
- str::from_utf8_slice_opt(self.container_as_bytes())
- }
- /// Returns whether .container_as_str() is guaranteed to not fail
- // FIXME (#8888): Remove unused arg once ::<for T> works
- #[inline]
- fn is_str(_: Option<Self>) -> bool { false }
-}
-
-/// A trait that represents the unsafe operations on GenericPaths
-pub trait GenericPathUnsafe {
- /// Creates a new Path without checking for null bytes.
- /// The resulting Path will always be normalized.
- unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Self;
-
- /// Replaces the filename portion of the path without checking for null
- /// bytes.
- /// See `set_filename` for details.
- unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T);
-
- /// Pushes a path onto `self` without checking for null bytes.
- /// See `push` for details.
- unsafe fn push_unchecked<T: BytesContainer>(&mut self, path: T);
-}
-
-/// Helper struct for printing paths with format!()
-pub struct Display<'self, P> {
- priv path: &'self P,
- priv filename: bool
-}
-
-impl<'self, P: GenericPath> fmt::Default for Display<'self, P> {
- fn fmt(d: &Display<P>, f: &mut fmt::Formatter) {
- d.with_str(|s| f.pad(s))
- }
-}
-
-impl<'self, P: GenericPath> ToStr for Display<'self, P> {
- /// Returns the path as a string
- ///
- /// If the path is not UTF-8, invalid sequences with be replaced with the
- /// unicode replacement char. This involves allocation.
- fn to_str(&self) -> ~str {
- if self.filename {
- match self.path.filename() {
- None => ~"",
- Some(v) => from_utf8_with_replacement(v)
- }
- } else {
- from_utf8_with_replacement(self.path.as_vec())
- }
- }
-}
-
-impl<'self, P: GenericPath> Display<'self, P> {
- /// Provides the path as a string to a closure
- ///
- /// If the path is not UTF-8, invalid sequences will be replaced with the
- /// unicode replacement char. This involves allocation.
- #[inline]
- pub fn with_str<T>(&self, f: |&str| -> T) -> T {
- let opt = if self.filename { self.path.filename_str() }
- else { self.path.as_str() };
- match opt {
- Some(s) => f(s),
- None => {
- let s = self.to_str();
- f(s.as_slice())
- }
- }
- }
-}
-
-impl<'self> BytesContainer for &'self str {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_bytes()
- }
- #[inline]
- fn container_as_str<'a>(&'a self) -> &'a str {
- *self
- }
- #[inline]
- fn container_as_str_opt<'a>(&'a self) -> Option<&'a str> {
- Some(*self)
- }
- #[inline]
- fn is_str(_: Option<&'self str>) -> bool { true }
-}
-
-impl BytesContainer for ~str {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_bytes()
- }
- #[inline]
- fn container_into_owned_bytes(self) -> ~[u8] {
- self.into_bytes()
- }
- #[inline]
- fn container_as_str<'a>(&'a self) -> &'a str {
- self.as_slice()
- }
- #[inline]
- fn container_as_str_opt<'a>(&'a self) -> Option<&'a str> {
- Some(self.as_slice())
- }
- #[inline]
- fn is_str(_: Option<~str>) -> bool { true }
-}
-
-impl BytesContainer for @str {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_bytes()
- }
- #[inline]
- fn container_as_str<'a>(&'a self) -> &'a str {
- self.as_slice()
- }
- #[inline]
- fn container_as_str_opt<'a>(&'a self) -> Option<&'a str> {
- Some(self.as_slice())
- }
- #[inline]
- fn is_str(_: Option<@str>) -> bool { true }
-}
-
-impl<'self> BytesContainer for &'self [u8] {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- *self
- }
-}
-
-impl BytesContainer for ~[u8] {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_slice()
- }
- #[inline]
- fn container_into_owned_bytes(self) -> ~[u8] {
- self
- }
-}
-
-impl BytesContainer for @[u8] {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_slice()
- }
-}
-
-impl BytesContainer for CString {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- let s = self.as_bytes();
- s.slice_to(s.len()-1)
- }
-}
-
-#[inline(always)]
-fn contains_nul(v: &[u8]) -> bool {
- v.iter().any(|&x| x == 0)
-}
-
-#[inline(always)]
-fn from_utf8_with_replacement(mut v: &[u8]) -> ~str {
- // FIXME (#9516): Don't decode utf-8 manually here once we have a good way to do it in str
- // This is a truly horrifically bad implementation, done as a functionality stopgap until
- // we have a proper utf-8 decoder. I don't really want to write one here.
- static REPLACEMENT_CHAR: char = '\uFFFD';
-
- let mut s = str::with_capacity(v.len());
- while !v.is_empty() {
- let w = str::utf8_char_width(v[0]);
- if w == 0u {
- s.push_char(REPLACEMENT_CHAR);
- v = v.slice_from(1);
- } else if v.len() < w || !str::is_utf8(v.slice_to(w)) {
- s.push_char(REPLACEMENT_CHAR);
- v = v.slice_from(1);
- } else {
- s.push_str(unsafe { ::cast::transmute(v.slice_to(w)) });
- v = v.slice_from(w);
- }
- }
- s
-}
-#[cfg(test)]
-mod tests {
- use super::{GenericPath, PosixPath, WindowsPath};
- use c_str::ToCStr;
-
- #[test]
- fn test_cstring() {
- let input = "/foo/bar/baz";
- let path: PosixPath = PosixPath::new(input.to_c_str());
- assert_eq!(path.as_vec(), input.as_bytes());
-
- let input = r"\foo\bar\baz";
- let path: WindowsPath = WindowsPath::new(input.to_c_str());
- assert_eq!(path.as_str().unwrap(), input.as_slice());
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! POSIX file path handling
-
-use container::Container;
-use c_str::{CString, ToCStr};
-use clone::Clone;
-use cmp::Eq;
-use from_str::FromStr;
-use iter::{AdditiveIterator, Extendable, Iterator, Map};
-use option::{Option, None, Some};
-use str;
-use str::Str;
-use to_bytes::IterBytes;
-use vec;
-use vec::{CopyableVector, RSplitIterator, SplitIterator, Vector, VectorVector};
-use super::{BytesContainer, GenericPath, GenericPathUnsafe};
-
-/// Iterator that yields successive components of a Path as &[u8]
-pub type ComponentIter<'self> = SplitIterator<'self, u8>;
-/// Iterator that yields components of a Path in reverse as &[u8]
-pub type RevComponentIter<'self> = RSplitIterator<'self, u8>;
-
-/// Iterator that yields successive components of a Path as Option<&str>
-pub type StrComponentIter<'self> = Map<'self, &'self [u8], Option<&'self str>,
- ComponentIter<'self>>;
-/// Iterator that yields components of a Path in reverse as Option<&str>
-pub type RevStrComponentIter<'self> = Map<'self, &'self [u8], Option<&'self str>,
- RevComponentIter<'self>>;
-
-/// Represents a POSIX file path
-#[deriving(Clone, DeepClone)]
-pub struct Path {
- priv repr: ~[u8], // assumed to never be empty or contain NULs
- priv sepidx: Option<uint> // index of the final separator in repr
-}
-
-/// The standard path separator character
-pub static sep: char = '/';
-static sep_byte: u8 = sep as u8;
-
-/// Returns whether the given byte is a path separator
-#[inline]
-pub fn is_sep_byte(u: &u8) -> bool {
- *u as char == sep
-}
-
-/// Returns whether the given char is a path separator
-#[inline]
-pub fn is_sep(c: char) -> bool {
- c == sep
-}
-
-impl Eq for Path {
- #[inline]
- fn eq(&self, other: &Path) -> bool {
- self.repr == other.repr
- }
-}
-
-impl FromStr for Path {
- fn from_str(s: &str) -> Option<Path> {
- Path::new_opt(s)
- }
-}
-
-impl ToCStr for Path {
- #[inline]
- fn to_c_str(&self) -> CString {
- // The Path impl guarantees no internal NUL
- unsafe { self.as_vec().to_c_str_unchecked() }
- }
-
- #[inline]
- unsafe fn to_c_str_unchecked(&self) -> CString {
- self.as_vec().to_c_str_unchecked()
- }
-}
-
-impl IterBytes for Path {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: |buf: &[u8]| -> bool) -> bool {
- self.repr.iter_bytes(lsb0, f)
- }
-}
-
-impl BytesContainer for Path {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_vec()
- }
- #[inline]
- fn container_into_owned_bytes(self) -> ~[u8] {
- self.into_vec()
- }
-}
-
-impl<'self> BytesContainer for &'self Path {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_vec()
- }
-}
-
-impl GenericPathUnsafe for Path {
- unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Path {
- let path = Path::normalize(path.container_as_bytes());
- assert!(!path.is_empty());
- let idx = path.rposition_elem(&sep_byte);
- Path{ repr: path, sepidx: idx }
- }
-
- unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
- let filename = filename.container_as_bytes();
- match self.sepidx {
- None if bytes!("..") == self.repr => {
- let mut v = vec::with_capacity(3 + filename.len());
- v.push_all(dot_dot_static);
- v.push(sep_byte);
- v.push_all(filename);
- self.repr = Path::normalize(v);
- }
- None => {
- self.repr = Path::normalize(filename);
- }
- Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => {
- let mut v = vec::with_capacity(self.repr.len() + 1 + filename.len());
- v.push_all(self.repr);
- v.push(sep_byte);
- v.push_all(filename);
- self.repr = Path::normalize(v);
- }
- Some(idx) => {
- let mut v = vec::with_capacity(idx + 1 + filename.len());
- v.push_all(self.repr.slice_to(idx+1));
- v.push_all(filename);
- self.repr = Path::normalize(v);
- }
- }
- self.sepidx = self.repr.rposition_elem(&sep_byte);
- }
-
- unsafe fn push_unchecked<T: BytesContainer>(&mut self, path: T) {
- let path = path.container_as_bytes();
- if !path.is_empty() {
- if path[0] == sep_byte {
- self.repr = Path::normalize(path);
- } else {
- let mut v = vec::with_capacity(self.repr.len() + path.len() + 1);
- v.push_all(self.repr);
- v.push(sep_byte);
- v.push_all(path);
- self.repr = Path::normalize(v);
- }
- self.sepidx = self.repr.rposition_elem(&sep_byte);
- }
- }
-}
-
-impl GenericPath for Path {
- #[inline]
- fn as_vec<'a>(&'a self) -> &'a [u8] {
- self.repr.as_slice()
- }
-
- fn into_vec(self) -> ~[u8] {
- self.repr
- }
-
- fn dirname<'a>(&'a self) -> &'a [u8] {
- match self.sepidx {
- None if bytes!("..") == self.repr => self.repr.as_slice(),
- None => dot_static,
- Some(0) => self.repr.slice_to(1),
- Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => self.repr.as_slice(),
- Some(idx) => self.repr.slice_to(idx)
- }
- }
-
- fn filename<'a>(&'a self) -> Option<&'a [u8]> {
- match self.sepidx {
- None if bytes!(".") == self.repr || bytes!("..") == self.repr => None,
- None => Some(self.repr.as_slice()),
- Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => None,
- Some(0) if self.repr.slice_from(1).is_empty() => None,
- Some(idx) => Some(self.repr.slice_from(idx+1))
- }
- }
-
- fn pop(&mut self) -> bool {
- match self.sepidx {
- None if bytes!(".") == self.repr => false,
- None => {
- self.repr = ~['.' as u8];
- self.sepidx = None;
- true
- }
- Some(0) if bytes!("/") == self.repr => false,
- Some(idx) => {
- if idx == 0 {
- self.repr.truncate(idx+1);
- } else {
- self.repr.truncate(idx);
- }
- self.sepidx = self.repr.rposition_elem(&sep_byte);
- true
- }
- }
- }
-
- fn root_path(&self) -> Option<Path> {
- if self.is_absolute() {
- Some(Path::new("/"))
- } else {
- None
- }
- }
-
- #[inline]
- fn is_absolute(&self) -> bool {
- self.repr[0] == sep_byte
- }
-
- fn is_ancestor_of(&self, other: &Path) -> bool {
- if self.is_absolute() != other.is_absolute() {
- false
- } else {
- let mut ita = self.components();
- let mut itb = other.components();
- if bytes!(".") == self.repr {
- return itb.next() != Some(bytes!(".."));
- }
- loop {
- match (ita.next(), itb.next()) {
- (None, _) => break,
- (Some(a), Some(b)) if a == b => { continue },
- (Some(a), _) if a == bytes!("..") => {
- // if ita contains only .. components, it's an ancestor
- return ita.all(|x| x == bytes!(".."));
- }
- _ => return false
- }
- }
- true
- }
- }
-
- fn path_relative_from(&self, base: &Path) -> Option<Path> {
- if self.is_absolute() != base.is_absolute() {
- if self.is_absolute() {
- Some(self.clone())
- } else {
- None
- }
- } else {
- let mut ita = self.components();
- let mut itb = base.components();
- let mut comps = ~[];
- loop {
- match (ita.next(), itb.next()) {
- (None, None) => break,
- (Some(a), None) => {
- comps.push(a);
- comps.extend(&mut ita);
- break;
- }
- (None, _) => comps.push(dot_dot_static),
- (Some(a), Some(b)) if comps.is_empty() && a == b => (),
- (Some(a), Some(b)) if b == bytes!(".") => comps.push(a),
- (Some(_), Some(b)) if b == bytes!("..") => return None,
- (Some(a), Some(_)) => {
- comps.push(dot_dot_static);
- for _ in itb {
- comps.push(dot_dot_static);
- }
- comps.push(a);
- comps.extend(&mut ita);
- break;
- }
- }
- }
- Some(Path::new(comps.connect_vec(&sep_byte)))
- }
- }
-
- fn ends_with_path(&self, child: &Path) -> bool {
- if !child.is_relative() { return false; }
- let mut selfit = self.rev_components();
- let mut childit = child.rev_components();
- loop {
- match (selfit.next(), childit.next()) {
- (Some(a), Some(b)) => if a != b { return false; },
- (Some(_), None) => break,
- (None, Some(_)) => return false,
- (None, None) => break
- }
- }
- true
- }
-}
-
-impl Path {
- /// Returns a new Path from a byte vector or string
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the vector contains a NUL.
- #[inline]
- pub fn new<T: BytesContainer>(path: T) -> Path {
- GenericPath::new(path)
- }
-
- /// Returns a new Path from a byte vector or string, if possible
- #[inline]
- pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
- GenericPath::new_opt(path)
- }
-
- /// Returns a normalized byte vector representation of a path, by removing all empty
- /// components, and unnecessary . and .. components.
- fn normalize<V: Vector<u8>+CopyableVector<u8>>(v: V) -> ~[u8] {
- // borrowck is being very picky
- let val = {
- let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == sep_byte;
- let v_ = if is_abs { v.as_slice().slice_from(1) } else { v.as_slice() };
- let comps = normalize_helper(v_, is_abs);
- match comps {
- None => None,
- Some(comps) => {
- if is_abs && comps.is_empty() {
- Some(~[sep_byte])
- } else {
- let n = if is_abs { comps.len() } else { comps.len() - 1} +
- comps.iter().map(|v| v.len()).sum();
- let mut v = vec::with_capacity(n);
- let mut it = comps.move_iter();
- if !is_abs {
- match it.next() {
- None => (),
- Some(comp) => v.push_all(comp)
- }
- }
- for comp in it {
- v.push(sep_byte);
- v.push_all(comp);
- }
- Some(v)
- }
- }
- }
- };
- match val {
- None => v.into_owned(),
- Some(val) => val
- }
- }
-
- /// Returns an iterator that yields each component of the path in turn.
- /// Does not distinguish between absolute and relative paths, e.g.
- /// /a/b/c and a/b/c yield the same set of components.
- /// A path of "/" yields no components. A path of "." yields one component.
- pub fn components<'a>(&'a self) -> ComponentIter<'a> {
- let v = if self.repr[0] == sep_byte {
- self.repr.slice_from(1)
- } else { self.repr.as_slice() };
- let mut ret = v.split(is_sep_byte);
- if v.is_empty() {
- // consume the empty "" component
- ret.next();
- }
- ret
- }
-
- /// Returns an iterator that yields each component of the path in reverse.
- /// See components() for details.
- pub fn rev_components<'a>(&'a self) -> RevComponentIter<'a> {
- let v = if self.repr[0] == sep_byte {
- self.repr.slice_from(1)
- } else { self.repr.as_slice() };
- let mut ret = v.rsplit(is_sep_byte);
- if v.is_empty() {
- // consume the empty "" component
- ret.next();
- }
- ret
- }
-
- /// Returns an iterator that yields each component of the path as Option<&str>.
- /// See components() for details.
- pub fn str_components<'a>(&'a self) -> StrComponentIter<'a> {
- self.components().map(str::from_utf8_slice_opt)
- }
-
- /// Returns an iterator that yields each component of the path in reverse as Option<&str>.
- /// See components() for details.
- pub fn rev_str_components<'a>(&'a self) -> RevStrComponentIter<'a> {
- self.rev_components().map(str::from_utf8_slice_opt)
- }
-}
-
-// None result means the byte vector didn't need normalizing
-fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<~[&'a [u8]]> {
- if is_abs && v.as_slice().is_empty() {
- return None;
- }
- let mut comps: ~[&'a [u8]] = ~[];
- let mut n_up = 0u;
- let mut changed = false;
- for comp in v.split(is_sep_byte) {
- if comp.is_empty() { changed = true }
- else if comp == bytes!(".") { changed = true }
- else if comp == bytes!("..") {
- if is_abs && comps.is_empty() { changed = true }
- else if comps.len() == n_up { comps.push(dot_dot_static); n_up += 1 }
- else { comps.pop(); changed = true }
- } else { comps.push(comp) }
- }
- if changed {
- if comps.is_empty() && !is_abs {
- if v == bytes!(".") {
- return None;
- }
- comps.push(dot_static);
- }
- Some(comps)
- } else {
- None
- }
-}
-
-static dot_static: &'static [u8] = bytes!(".");
-static dot_dot_static: &'static [u8] = bytes!("..");
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use option::{Option, Some, None};
- use iter::Iterator;
- use str;
- use vec::Vector;
-
- macro_rules! t(
- (s: $path:expr, $exp:expr) => (
- {
- let path = $path;
- assert_eq!(path.as_str(), Some($exp));
- }
- );
- (v: $path:expr, $exp:expr) => (
- {
- let path = $path;
- assert_eq!(path.as_vec(), $exp);
- }
- )
- )
-
- macro_rules! b(
- ($($arg:expr),+) => (
- bytes!($($arg),+)
- )
- )
-
- #[test]
- fn test_paths() {
- let empty: &[u8] = [];
- t!(v: Path::new(empty), b!("."));
- t!(v: Path::new(b!("/")), b!("/"));
- t!(v: Path::new(b!("a/b/c")), b!("a/b/c"));
- t!(v: Path::new(b!("a/b/c", 0xff)), b!("a/b/c", 0xff));
- t!(v: Path::new(b!(0xff, "/../foo", 0x80)), b!("foo", 0x80));
- let p = Path::new(b!("a/b/c", 0xff));
- assert_eq!(p.as_str(), None);
-
- t!(s: Path::new(""), ".");
- t!(s: Path::new("/"), "/");
- t!(s: Path::new("hi"), "hi");
- t!(s: Path::new("hi/"), "hi");
- t!(s: Path::new("/lib"), "/lib");
- t!(s: Path::new("/lib/"), "/lib");
- t!(s: Path::new("hi/there"), "hi/there");
- t!(s: Path::new("hi/there.txt"), "hi/there.txt");
-
- t!(s: Path::new("hi/there/"), "hi/there");
- t!(s: Path::new("hi/../there"), "there");
- t!(s: Path::new("../hi/there"), "../hi/there");
- t!(s: Path::new("/../hi/there"), "/hi/there");
- t!(s: Path::new("foo/.."), ".");
- t!(s: Path::new("/foo/.."), "/");
- t!(s: Path::new("/foo/../.."), "/");
- t!(s: Path::new("/foo/../../bar"), "/bar");
- t!(s: Path::new("/./hi/./there/."), "/hi/there");
- t!(s: Path::new("/./hi/./there/./.."), "/hi");
- t!(s: Path::new("foo/../.."), "..");
- t!(s: Path::new("foo/../../.."), "../..");
- t!(s: Path::new("foo/../../bar"), "../bar");
-
- assert_eq!(Path::new(b!("foo/bar")).into_vec(), b!("foo/bar").to_owned());
- assert_eq!(Path::new(b!("/foo/../../bar")).into_vec(),
- b!("/bar").to_owned());
-
- let p = Path::new(b!("foo/bar", 0x80));
- assert_eq!(p.as_str(), None);
- }
-
- #[test]
- fn test_opt_paths() {
- assert_eq!(Path::new_opt(b!("foo/bar", 0)), None);
- t!(v: Path::new_opt(b!("foo/bar")).unwrap(), b!("foo/bar"));
- assert_eq!(Path::new_opt("foo/bar\0"), None);
- t!(s: Path::new_opt("foo/bar").unwrap(), "foo/bar");
- }
-
- #[test]
- fn test_null_byte() {
- use path::null_byte::cond;
-
- let mut handled = false;
- let mut p = cond.trap(|v| {
- handled = true;
- assert_eq!(v.as_slice(), b!("foo/bar", 0));
- (b!("/bar").to_owned())
- }).inside(|| {
- Path::new(b!("foo/bar", 0))
- });
- assert!(handled);
- assert_eq!(p.as_vec(), b!("/bar"));
-
- handled = false;
- cond.trap(|v| {
- handled = true;
- assert_eq!(v.as_slice(), b!("f", 0, "o"));
- (b!("foo").to_owned())
- }).inside(|| {
- p.set_filename(b!("f", 0, "o"))
- });
- assert!(handled);
- assert_eq!(p.as_vec(), b!("/foo"));
-
- handled = false;
- cond.trap(|v| {
- handled = true;
- assert_eq!(v.as_slice(), b!("f", 0, "o"));
- (b!("foo").to_owned())
- }).inside(|| {
- p.push(b!("f", 0, "o"));
- });
- assert!(handled);
- assert_eq!(p.as_vec(), b!("/foo/foo"));
- }
-
- #[test]
- fn test_null_byte_fail() {
- use path::null_byte::cond;
- use task;
-
- macro_rules! t(
- ($name:expr => $code:block) => (
- {
- let mut t = task::task();
- t.name($name);
- let res = do t.try $code;
- assert!(res.is_err());
- }
- )
- )
-
- t!(~"new() w/nul" => {
- cond.trap(|_| {
- (b!("null", 0).to_owned())
- }).inside(|| {
- Path::new(b!("foo/bar", 0))
- });
- })
-
- t!(~"set_filename w/nul" => {
- let mut p = Path::new(b!("foo/bar"));
- cond.trap(|_| {
- (b!("null", 0).to_owned())
- }).inside(|| {
- p.set_filename(b!("foo", 0))
- });
- })
-
- t!(~"push w/nul" => {
- let mut p = Path::new(b!("foo/bar"));
- cond.trap(|_| {
- (b!("null", 0).to_owned())
- }).inside(|| {
- p.push(b!("foo", 0))
- });
- })
- }
-
- #[test]
- fn test_display_str() {
- macro_rules! t(
- ($path:expr, $disp:ident, $exp:expr) => (
- {
- let path = Path::new($path);
- assert_eq!(path.$disp().to_str(), ~$exp);
- }
- )
- )
- t!("foo", display, "foo");
- t!(b!("foo", 0x80), display, "foo\uFFFD");
- t!(b!("foo", 0xff, "bar"), display, "foo\uFFFDbar");
- t!(b!("foo", 0xff, "/bar"), filename_display, "bar");
- t!(b!("foo/", 0xff, "bar"), filename_display, "\uFFFDbar");
- t!(b!("/"), filename_display, "");
-
- macro_rules! t(
- ($path:expr, $exp:expr) => (
- {
- let mut called = false;
- let path = Path::new($path);
- path.display().with_str(|s| {
- assert_eq!(s, $exp);
- called = true;
- });
- assert!(called);
- }
- );
- ($path:expr, $exp:expr, filename) => (
- {
- let mut called = false;
- let path = Path::new($path);
- path.filename_display().with_str(|s| {
- assert_eq!(s, $exp);
- called = true;
- });
- assert!(called);
- }
- )
- )
-
- t!("foo", "foo");
- t!(b!("foo", 0x80), "foo\uFFFD");
- t!(b!("foo", 0xff, "bar"), "foo\uFFFDbar");
- t!(b!("foo", 0xff, "/bar"), "bar", filename);
- t!(b!("foo/", 0xff, "bar"), "\uFFFDbar", filename);
- t!(b!("/"), "", filename);
- }
-
- #[test]
- fn test_display() {
- macro_rules! t(
- ($path:expr, $exp:expr, $expf:expr) => (
- {
- let path = Path::new($path);
- let f = format!("{}", path.display());
- assert_eq!(f.as_slice(), $exp);
- let f = format!("{}", path.filename_display());
- assert_eq!(f.as_slice(), $expf);
- }
- )
- )
-
- t!(b!("foo"), "foo", "foo");
- t!(b!("foo/bar"), "foo/bar", "bar");
- t!(b!("/"), "/", "");
- t!(b!("foo", 0xff), "foo\uFFFD", "foo\uFFFD");
- t!(b!("foo", 0xff, "/bar"), "foo\uFFFD/bar", "bar");
- t!(b!("foo/", 0xff, "bar"), "foo/\uFFFDbar", "\uFFFDbar");
- t!(b!(0xff, "foo/bar", 0xff), "\uFFFDfoo/bar\uFFFD", "bar\uFFFD");
- }
-
- #[test]
- fn test_components() {
- macro_rules! t(
- (s: $path:expr, $op:ident, $exp:expr) => (
- {
- let path = Path::new($path);
- assert_eq!(path.$op(), ($exp).as_bytes());
- }
- );
- (s: $path:expr, $op:ident, $exp:expr, opt) => (
- {
- let path = Path::new($path);
- let left = path.$op().map(|x| str::from_utf8_slice(x));
- assert_eq!(left, $exp);
- }
- );
- (v: $path:expr, $op:ident, $exp:expr) => (
- {
- let path = Path::new($path);
- assert_eq!(path.$op(), $exp);
- }
- );
- )
-
- t!(v: b!("a/b/c"), filename, Some(b!("c")));
- t!(v: b!("a/b/c", 0xff), filename, Some(b!("c", 0xff)));
- t!(v: b!("a/b", 0xff, "/c"), filename, Some(b!("c")));
- t!(s: "a/b/c", filename, Some("c"), opt);
- t!(s: "/a/b/c", filename, Some("c"), opt);
- t!(s: "a", filename, Some("a"), opt);
- t!(s: "/a", filename, Some("a"), opt);
- t!(s: ".", filename, None, opt);
- t!(s: "/", filename, None, opt);
- t!(s: "..", filename, None, opt);
- t!(s: "../..", filename, None, opt);
-
- t!(v: b!("a/b/c"), dirname, b!("a/b"));
- t!(v: b!("a/b/c", 0xff), dirname, b!("a/b"));
- t!(v: b!("a/b", 0xff, "/c"), dirname, b!("a/b", 0xff));
- t!(s: "a/b/c", dirname, "a/b");
- t!(s: "/a/b/c", dirname, "/a/b");
- t!(s: "a", dirname, ".");
- t!(s: "/a", dirname, "/");
- t!(s: ".", dirname, ".");
- t!(s: "/", dirname, "/");
- t!(s: "..", dirname, "..");
- t!(s: "../..", dirname, "../..");
-
- t!(v: b!("hi/there.txt"), filestem, Some(b!("there")));
- t!(v: b!("hi/there", 0x80, ".txt"), filestem, Some(b!("there", 0x80)));
- t!(v: b!("hi/there.t", 0x80, "xt"), filestem, Some(b!("there")));
- t!(s: "hi/there.txt", filestem, Some("there"), opt);
- t!(s: "hi/there", filestem, Some("there"), opt);
- t!(s: "there.txt", filestem, Some("there"), opt);
- t!(s: "there", filestem, Some("there"), opt);
- t!(s: ".", filestem, None, opt);
- t!(s: "/", filestem, None, opt);
- t!(s: "foo/.bar", filestem, Some(".bar"), opt);
- t!(s: ".bar", filestem, Some(".bar"), opt);
- t!(s: "..bar", filestem, Some("."), opt);
- t!(s: "hi/there..txt", filestem, Some("there."), opt);
- t!(s: "..", filestem, None, opt);
- t!(s: "../..", filestem, None, opt);
-
- t!(v: b!("hi/there.txt"), extension, Some(b!("txt")));
- t!(v: b!("hi/there", 0x80, ".txt"), extension, Some(b!("txt")));
- t!(v: b!("hi/there.t", 0x80, "xt"), extension, Some(b!("t", 0x80, "xt")));
- t!(v: b!("hi/there"), extension, None);
- t!(v: b!("hi/there", 0x80), extension, None);
- t!(s: "hi/there.txt", extension, Some("txt"), opt);
- t!(s: "hi/there", extension, None, opt);
- t!(s: "there.txt", extension, Some("txt"), opt);
- t!(s: "there", extension, None, opt);
- t!(s: ".", extension, None, opt);
- t!(s: "/", extension, None, opt);
- t!(s: "foo/.bar", extension, None, opt);
- t!(s: ".bar", extension, None, opt);
- t!(s: "..bar", extension, Some("bar"), opt);
- t!(s: "hi/there..txt", extension, Some("txt"), opt);
- t!(s: "..", extension, None, opt);
- t!(s: "../..", extension, None, opt);
- }
-
- #[test]
- fn test_push() {
- macro_rules! t(
- (s: $path:expr, $join:expr) => (
- {
- let path = ($path);
- let join = ($join);
- let mut p1 = Path::new(path);
- let p2 = p1.clone();
- p1.push(join);
- assert_eq!(p1, p2.join(join));
- }
- )
- )
-
- t!(s: "a/b/c", "..");
- t!(s: "/a/b/c", "d");
- t!(s: "a/b", "c/d");
- t!(s: "a/b", "/c/d");
- }
-
- #[test]
- fn test_push_path() {
- macro_rules! t(
- (s: $path:expr, $push:expr, $exp:expr) => (
- {
- let mut p = Path::new($path);
- let push = Path::new($push);
- p.push(&push);
- assert_eq!(p.as_str(), Some($exp));
- }
- )
- )
-
- t!(s: "a/b/c", "d", "a/b/c/d");
- t!(s: "/a/b/c", "d", "/a/b/c/d");
- t!(s: "a/b", "c/d", "a/b/c/d");
- t!(s: "a/b", "/c/d", "/c/d");
- t!(s: "a/b", ".", "a/b");
- t!(s: "a/b", "../c", "a/c");
- }
-
- #[test]
- fn test_push_many() {
- use to_man = at_vec::to_managed_move;
-
- macro_rules! t(
- (s: $path:expr, $push:expr, $exp:expr) => (
- {
- let mut p = Path::new($path);
- p.push_many($push);
- assert_eq!(p.as_str(), Some($exp));
- }
- );
- (v: $path:expr, $push:expr, $exp:expr) => (
- {
- let mut p = Path::new($path);
- p.push_many($push);
- assert_eq!(p.as_vec(), $exp);
- }
- )
- )
-
- t!(s: "a/b/c", ["d", "e"], "a/b/c/d/e");
- t!(s: "a/b/c", ["d", "/e"], "/e");
- t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
- t!(s: "a/b/c", [~"d", ~"e"], "a/b/c/d/e");
- t!(s: "a/b/c", [@"d", @"e"], "a/b/c/d/e");
- t!(v: b!("a/b/c"), [b!("d"), b!("e")], b!("a/b/c/d/e"));
- t!(v: b!("a/b/c"), [b!("d"), b!("/e"), b!("f")], b!("/e/f"));
- t!(v: b!("a/b/c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a/b/c/d/e"));
- t!(v: b!("a/b/c"), [to_man(b!("d").to_owned()), to_man(b!("e").to_owned())],
- b!("a/b/c/d/e"));
- }
-
- #[test]
- fn test_pop() {
- macro_rules! t(
- (s: $path:expr, $left:expr, $right:expr) => (
- {
- let mut p = Path::new($path);
- let result = p.pop();
- assert_eq!(p.as_str(), Some($left));
- assert_eq!(result, $right);
- }
- );
- (v: [$($path:expr),+], [$($left:expr),+], $right:expr) => (
- {
- let mut p = Path::new(b!($($path),+));
- let result = p.pop();
- assert_eq!(p.as_vec(), b!($($left),+));
- assert_eq!(result, $right);
- }
- )
- )
-
- t!(v: ["a/b/c"], ["a/b"], true);
- t!(v: ["a"], ["."], true);
- t!(v: ["."], ["."], false);
- t!(v: ["/a"], ["/"], true);
- t!(v: ["/"], ["/"], false);
- t!(v: ["a/b/c", 0x80], ["a/b"], true);
- t!(v: ["a/b", 0x80, "/c"], ["a/b", 0x80], true);
- t!(v: [0xff], ["."], true);
- t!(v: ["/", 0xff], ["/"], true);
- t!(s: "a/b/c", "a/b", true);
- t!(s: "a", ".", true);
- t!(s: ".", ".", false);
- t!(s: "/a", "/", true);
- t!(s: "/", "/", false);
- }
-
- #[test]
- fn test_root_path() {
- assert_eq!(Path::new(b!("a/b/c")).root_path(), None);
- assert_eq!(Path::new(b!("/a/b/c")).root_path(), Some(Path::new("/")));
- }
-
- #[test]
- fn test_join() {
- t!(v: Path::new(b!("a/b/c")).join(b!("..")), b!("a/b"));
- t!(v: Path::new(b!("/a/b/c")).join(b!("d")), b!("/a/b/c/d"));
- t!(v: Path::new(b!("a/", 0x80, "/c")).join(b!(0xff)), b!("a/", 0x80, "/c/", 0xff));
- t!(s: Path::new("a/b/c").join(".."), "a/b");
- t!(s: Path::new("/a/b/c").join("d"), "/a/b/c/d");
- t!(s: Path::new("a/b").join("c/d"), "a/b/c/d");
- t!(s: Path::new("a/b").join("/c/d"), "/c/d");
- t!(s: Path::new(".").join("a/b"), "a/b");
- t!(s: Path::new("/").join("a/b"), "/a/b");
- }
-
- #[test]
- fn test_join_path() {
- macro_rules! t(
- (s: $path:expr, $join:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let join = Path::new($join);
- let res = path.join(&join);
- assert_eq!(res.as_str(), Some($exp));
- }
- )
- )
-
- t!(s: "a/b/c", "..", "a/b");
- t!(s: "/a/b/c", "d", "/a/b/c/d");
- t!(s: "a/b", "c/d", "a/b/c/d");
- t!(s: "a/b", "/c/d", "/c/d");
- t!(s: ".", "a/b", "a/b");
- t!(s: "/", "a/b", "/a/b");
- }
-
- #[test]
- fn test_join_many() {
- use to_man = at_vec::to_managed_move;
-
- macro_rules! t(
- (s: $path:expr, $join:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let res = path.join_many($join);
- assert_eq!(res.as_str(), Some($exp));
- }
- );
- (v: $path:expr, $join:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let res = path.join_many($join);
- assert_eq!(res.as_vec(), $exp);
- }
- )
- )
-
- t!(s: "a/b/c", ["d", "e"], "a/b/c/d/e");
- t!(s: "a/b/c", ["..", "d"], "a/b/d");
- t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
- t!(s: "a/b/c", [~"d", ~"e"], "a/b/c/d/e");
- t!(s: "a/b/c", [@"d", @"e"], "a/b/c/d/e");
- t!(v: b!("a/b/c"), [b!("d"), b!("e")], b!("a/b/c/d/e"));
- t!(v: b!("a/b/c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a/b/c/d/e"));
- t!(v: b!("a/b/c"), [to_man(b!("d").to_owned()), to_man(b!("e").to_owned())],
- b!("a/b/c/d/e"));
- }
-
- #[test]
- fn test_with_helpers() {
- let empty: &[u8] = [];
-
- t!(v: Path::new(b!("a/b/c")).with_filename(b!("d")), b!("a/b/d"));
- t!(v: Path::new(b!("a/b/c", 0xff)).with_filename(b!(0x80)), b!("a/b/", 0x80));
- t!(v: Path::new(b!("/", 0xff, "/foo")).with_filename(b!(0xcd)),
- b!("/", 0xff, "/", 0xcd));
- t!(s: Path::new("a/b/c").with_filename("d"), "a/b/d");
- t!(s: Path::new(".").with_filename("foo"), "foo");
- t!(s: Path::new("/a/b/c").with_filename("d"), "/a/b/d");
- t!(s: Path::new("/").with_filename("foo"), "/foo");
- t!(s: Path::new("/a").with_filename("foo"), "/foo");
- t!(s: Path::new("foo").with_filename("bar"), "bar");
- t!(s: Path::new("/").with_filename("foo/"), "/foo");
- t!(s: Path::new("/a").with_filename("foo/"), "/foo");
- t!(s: Path::new("a/b/c").with_filename(""), "a/b");
- t!(s: Path::new("a/b/c").with_filename("."), "a/b");
- t!(s: Path::new("a/b/c").with_filename(".."), "a");
- t!(s: Path::new("/a").with_filename(""), "/");
- t!(s: Path::new("foo").with_filename(""), ".");
- t!(s: Path::new("a/b/c").with_filename("d/e"), "a/b/d/e");
- t!(s: Path::new("a/b/c").with_filename("/d"), "a/b/d");
- t!(s: Path::new("..").with_filename("foo"), "../foo");
- t!(s: Path::new("../..").with_filename("foo"), "../../foo");
- t!(s: Path::new("..").with_filename(""), "..");
- t!(s: Path::new("../..").with_filename(""), "../..");
-
- t!(v: Path::new(b!("hi/there", 0x80, ".txt")).with_extension(b!("exe")),
- b!("hi/there", 0x80, ".exe"));
- t!(v: Path::new(b!("hi/there.txt", 0x80)).with_extension(b!(0xff)),
- b!("hi/there.", 0xff));
- t!(v: Path::new(b!("hi/there", 0x80)).with_extension(b!(0xff)),
- b!("hi/there", 0x80, ".", 0xff));
- t!(v: Path::new(b!("hi/there.", 0xff)).with_extension(empty), b!("hi/there"));
- t!(s: Path::new("hi/there.txt").with_extension("exe"), "hi/there.exe");
- t!(s: Path::new("hi/there.txt").with_extension(""), "hi/there");
- t!(s: Path::new("hi/there.txt").with_extension("."), "hi/there..");
- t!(s: Path::new("hi/there.txt").with_extension(".."), "hi/there...");
- t!(s: Path::new("hi/there").with_extension("txt"), "hi/there.txt");
- t!(s: Path::new("hi/there").with_extension("."), "hi/there..");
- t!(s: Path::new("hi/there").with_extension(".."), "hi/there...");
- t!(s: Path::new("hi/there.").with_extension("txt"), "hi/there.txt");
- t!(s: Path::new("hi/.foo").with_extension("txt"), "hi/.foo.txt");
- t!(s: Path::new("hi/there.txt").with_extension(".foo"), "hi/there..foo");
- t!(s: Path::new("/").with_extension("txt"), "/");
- t!(s: Path::new("/").with_extension("."), "/");
- t!(s: Path::new("/").with_extension(".."), "/");
- t!(s: Path::new(".").with_extension("txt"), ".");
- }
-
- #[test]
- fn test_setters() {
- macro_rules! t(
- (s: $path:expr, $set:ident, $with:ident, $arg:expr) => (
- {
- let path = $path;
- let arg = $arg;
- let mut p1 = Path::new(path);
- p1.$set(arg);
- let p2 = Path::new(path);
- assert_eq!(p1, p2.$with(arg));
- }
- );
- (v: $path:expr, $set:ident, $with:ident, $arg:expr) => (
- {
- let path = $path;
- let arg = $arg;
- let mut p1 = Path::new(path);
- p1.$set(arg);
- let p2 = Path::new(path);
- assert_eq!(p1, p2.$with(arg));
- }
- )
- )
-
- t!(v: b!("a/b/c"), set_filename, with_filename, b!("d"));
- t!(v: b!("/"), set_filename, with_filename, b!("foo"));
- t!(v: b!(0x80), set_filename, with_filename, b!(0xff));
- t!(s: "a/b/c", set_filename, with_filename, "d");
- t!(s: "/", set_filename, with_filename, "foo");
- t!(s: ".", set_filename, with_filename, "foo");
- t!(s: "a/b", set_filename, with_filename, "");
- t!(s: "a", set_filename, with_filename, "");
-
- t!(v: b!("hi/there.txt"), set_extension, with_extension, b!("exe"));
- t!(v: b!("hi/there.t", 0x80, "xt"), set_extension, with_extension, b!("exe", 0xff));
- t!(s: "hi/there.txt", set_extension, with_extension, "exe");
- t!(s: "hi/there.", set_extension, with_extension, "txt");
- t!(s: "hi/there", set_extension, with_extension, "txt");
- t!(s: "hi/there.txt", set_extension, with_extension, "");
- t!(s: "hi/there", set_extension, with_extension, "");
- t!(s: ".", set_extension, with_extension, "txt");
- }
-
- #[test]
- fn test_getters() {
- macro_rules! t(
- (s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
- {
- let path = $path;
- let filename = $filename;
- assert!(path.filename_str() == filename,
- "{}.filename_str(): Expected `{:?}`, found {:?}",
- path.as_str().unwrap(), filename, path.filename_str());
- let dirname = $dirname;
- assert!(path.dirname_str() == dirname,
- "`{}`.dirname_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), dirname, path.dirname_str());
- let filestem = $filestem;
- assert!(path.filestem_str() == filestem,
- "`{}`.filestem_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), filestem, path.filestem_str());
- let ext = $ext;
- assert!(path.extension_str() == ext,
- "`{}`.extension_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), ext, path.extension_str());
- }
- );
- (v: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
- {
- let path = $path;
- assert_eq!(path.filename(), $filename);
- assert_eq!(path.dirname(), $dirname);
- assert_eq!(path.filestem(), $filestem);
- assert_eq!(path.extension(), $ext);
- }
- )
- )
-
- t!(v: Path::new(b!("a/b/c")), Some(b!("c")), b!("a/b"), Some(b!("c")), None);
- t!(v: Path::new(b!("a/b/", 0xff)), Some(b!(0xff)), b!("a/b"), Some(b!(0xff)), None);
- t!(v: Path::new(b!("hi/there.", 0xff)), Some(b!("there.", 0xff)), b!("hi"),
- Some(b!("there")), Some(b!(0xff)));
- t!(s: Path::new("a/b/c"), Some("c"), Some("a/b"), Some("c"), None);
- t!(s: Path::new("."), None, Some("."), None, None);
- t!(s: Path::new("/"), None, Some("/"), None, None);
- t!(s: Path::new(".."), None, Some(".."), None, None);
- t!(s: Path::new("../.."), None, Some("../.."), None, None);
- t!(s: Path::new("hi/there.txt"), Some("there.txt"), Some("hi"),
- Some("there"), Some("txt"));
- t!(s: Path::new("hi/there"), Some("there"), Some("hi"), Some("there"), None);
- t!(s: Path::new("hi/there."), Some("there."), Some("hi"),
- Some("there"), Some(""));
- t!(s: Path::new("hi/.there"), Some(".there"), Some("hi"), Some(".there"), None);
- t!(s: Path::new("hi/..there"), Some("..there"), Some("hi"),
- Some("."), Some("there"));
- t!(s: Path::new(b!("a/b/", 0xff)), None, Some("a/b"), None, None);
- t!(s: Path::new(b!("a/b/", 0xff, ".txt")), None, Some("a/b"), None, Some("txt"));
- t!(s: Path::new(b!("a/b/c.", 0x80)), None, Some("a/b"), Some("c"), None);
- t!(s: Path::new(b!(0xff, "/b")), Some("b"), None, Some("b"), None);
- }
-
- #[test]
- fn test_dir_path() {
- t!(v: Path::new(b!("hi/there", 0x80)).dir_path(), b!("hi"));
- t!(v: Path::new(b!("hi", 0xff, "/there")).dir_path(), b!("hi", 0xff));
- t!(s: Path::new("hi/there").dir_path(), "hi");
- t!(s: Path::new("hi").dir_path(), ".");
- t!(s: Path::new("/hi").dir_path(), "/");
- t!(s: Path::new("/").dir_path(), "/");
- t!(s: Path::new("..").dir_path(), "..");
- t!(s: Path::new("../..").dir_path(), "../..");
- }
-
- #[test]
- fn test_is_absolute() {
- macro_rules! t(
- (s: $path:expr, $abs:expr, $rel:expr) => (
- {
- let path = Path::new($path);
- assert_eq!(path.is_absolute(), $abs);
- assert_eq!(path.is_relative(), $rel);
- }
- )
- )
- t!(s: "a/b/c", false, true);
- t!(s: "/a/b/c", true, false);
- t!(s: "a", false, true);
- t!(s: "/a", true, false);
- t!(s: ".", false, true);
- t!(s: "/", true, false);
- t!(s: "..", false, true);
- t!(s: "../..", false, true);
- }
-
- #[test]
- fn test_is_ancestor_of() {
- macro_rules! t(
- (s: $path:expr, $dest:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let dest = Path::new($dest);
- assert_eq!(path.is_ancestor_of(&dest), $exp);
- }
- )
- )
-
- t!(s: "a/b/c", "a/b/c/d", true);
- t!(s: "a/b/c", "a/b/c", true);
- t!(s: "a/b/c", "a/b", false);
- t!(s: "/a/b/c", "/a/b/c", true);
- t!(s: "/a/b", "/a/b/c", true);
- t!(s: "/a/b/c/d", "/a/b/c", false);
- t!(s: "/a/b", "a/b/c", false);
- t!(s: "a/b", "/a/b/c", false);
- t!(s: "a/b/c", "a/b/d", false);
- t!(s: "../a/b/c", "a/b/c", false);
- t!(s: "a/b/c", "../a/b/c", false);
- t!(s: "a/b/c", "a/b/cd", false);
- t!(s: "a/b/cd", "a/b/c", false);
- t!(s: "../a/b", "../a/b/c", true);
- t!(s: ".", "a/b", true);
- t!(s: ".", ".", true);
- t!(s: "/", "/", true);
- t!(s: "/", "/a/b", true);
- t!(s: "..", "a/b", true);
- t!(s: "../..", "a/b", true);
- }
-
- #[test]
- fn test_ends_with_path() {
- macro_rules! t(
- (s: $path:expr, $child:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let child = Path::new($child);
- assert_eq!(path.ends_with_path(&child), $exp);
- }
- );
- (v: $path:expr, $child:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let child = Path::new($child);
- assert_eq!(path.ends_with_path(&child), $exp);
- }
- )
- )
-
- t!(s: "a/b/c", "c", true);
- t!(s: "a/b/c", "d", false);
- t!(s: "foo/bar/quux", "bar", false);
- t!(s: "foo/bar/quux", "barquux", false);
- t!(s: "a/b/c", "b/c", true);
- t!(s: "a/b/c", "a/b/c", true);
- t!(s: "a/b/c", "foo/a/b/c", false);
- t!(s: "/a/b/c", "a/b/c", true);
- t!(s: "/a/b/c", "/a/b/c", false); // child must be relative
- t!(s: "/a/b/c", "foo/a/b/c", false);
- t!(s: "a/b/c", "", false);
- t!(s: "", "", true);
- t!(s: "/a/b/c", "d/e/f", false);
- t!(s: "a/b/c", "a/b", false);
- t!(s: "a/b/c", "b", false);
- t!(v: b!("a/b/c"), b!("b/c"), true);
- t!(v: b!("a/b/", 0xff), b!(0xff), true);
- t!(v: b!("a/b/", 0xff), b!("b/", 0xff), true);
- }
-
- #[test]
- fn test_path_relative_from() {
- macro_rules! t(
- (s: $path:expr, $other:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let other = Path::new($other);
- let res = path.path_relative_from(&other);
- assert_eq!(res.as_ref().and_then(|x| x.as_str()), $exp);
- }
- )
- )
-
- t!(s: "a/b/c", "a/b", Some("c"));
- t!(s: "a/b/c", "a/b/d", Some("../c"));
- t!(s: "a/b/c", "a/b/c/d", Some(".."));
- t!(s: "a/b/c", "a/b/c", Some("."));
- t!(s: "a/b/c", "a/b/c/d/e", Some("../.."));
- t!(s: "a/b/c", "a/d/e", Some("../../b/c"));
- t!(s: "a/b/c", "d/e/f", Some("../../../a/b/c"));
- t!(s: "a/b/c", "/a/b/c", None);
- t!(s: "/a/b/c", "a/b/c", Some("/a/b/c"));
- t!(s: "/a/b/c", "/a/b/c/d", Some(".."));
- t!(s: "/a/b/c", "/a/b", Some("c"));
- t!(s: "/a/b/c", "/a/b/c/d/e", Some("../.."));
- t!(s: "/a/b/c", "/a/d/e", Some("../../b/c"));
- t!(s: "/a/b/c", "/d/e/f", Some("../../../a/b/c"));
- t!(s: "hi/there.txt", "hi/there", Some("../there.txt"));
- t!(s: ".", "a", Some(".."));
- t!(s: ".", "a/b", Some("../.."));
- t!(s: ".", ".", Some("."));
- t!(s: "a", ".", Some("a"));
- t!(s: "a/b", ".", Some("a/b"));
- t!(s: "..", ".", Some(".."));
- t!(s: "a/b/c", "a/b/c", Some("."));
- t!(s: "/a/b/c", "/a/b/c", Some("."));
- t!(s: "/", "/", Some("."));
- t!(s: "/", ".", Some("/"));
- t!(s: "../../a", "b", Some("../../../a"));
- t!(s: "a", "../../b", None);
- t!(s: "../../a", "../../b", Some("../a"));
- t!(s: "../../a", "../../a/b", Some(".."));
- t!(s: "../../a/b", "../../a", Some("b"));
- }
-
- #[test]
- fn test_components_iter() {
- macro_rules! t(
- (s: $path:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let comps = path.components().to_owned_vec();
- let exp: &[&str] = $exp;
- let exps = exp.iter().map(|x| x.as_bytes()).to_owned_vec();
- assert!(comps == exps, "components: Expected {:?}, found {:?}",
- comps, exps);
- let comps = path.rev_components().to_owned_vec();
- let exps = exps.move_rev_iter().to_owned_vec();
- assert!(comps == exps, "rev_components: Expected {:?}, found {:?}",
- comps, exps);
- }
- );
- (v: [$($arg:expr),+], [$([$($exp:expr),*]),*]) => (
- {
- let path = Path::new(b!($($arg),+));
- let comps = path.components().to_owned_vec();
- let exp: &[&[u8]] = [$(b!($($exp),*)),*];
- assert!(comps.as_slice() == exp, "components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- let comps = path.rev_components().to_owned_vec();
- let exp = exp.rev_iter().map(|&x|x).to_owned_vec();
- assert!(comps.as_slice() == exp,
- "rev_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- }
- )
- )
-
- t!(v: ["a/b/c"], [["a"], ["b"], ["c"]]);
- t!(v: ["/", 0xff, "/a/", 0x80], [[0xff], ["a"], [0x80]]);
- t!(v: ["../../foo", 0xcd, "bar"], [[".."], [".."], ["foo", 0xcd, "bar"]]);
- t!(s: "a/b/c", ["a", "b", "c"]);
- t!(s: "a/b/d", ["a", "b", "d"]);
- t!(s: "a/b/cd", ["a", "b", "cd"]);
- t!(s: "/a/b/c", ["a", "b", "c"]);
- t!(s: "a", ["a"]);
- t!(s: "/a", ["a"]);
- t!(s: "/", []);
- t!(s: ".", ["."]);
- t!(s: "..", [".."]);
- t!(s: "../..", ["..", ".."]);
- t!(s: "../../foo", ["..", "..", "foo"]);
- }
-
- #[test]
- fn test_str_components() {
- macro_rules! t(
- (v: [$($arg:expr),+], $exp:expr) => (
- {
- let path = Path::new(b!($($arg),+));
- let comps = path.str_components().to_owned_vec();
- let exp: &[Option<&str>] = $exp;
- assert!(comps.as_slice() == exp,
- "str_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- let comps = path.rev_str_components().to_owned_vec();
- let exp = exp.rev_iter().map(|&x|x).to_owned_vec();
- assert!(comps.as_slice() == exp,
- "rev_str_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- }
- )
- )
-
- t!(v: ["a/b/c"], [Some("a"), Some("b"), Some("c")]);
- t!(v: ["/", 0xff, "/a/", 0x80], [None, Some("a"), None]);
- t!(v: ["../../foo", 0xcd, "bar"], [Some(".."), Some(".."), None]);
- // str_components is a wrapper around components, so no need to do
- // the full set of tests
- }
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
- use super::*;
-
- #[bench]
- fn join_home_dir(bh: &mut BenchHarness) {
- let posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.join("home");
- });
- }
-
- #[bench]
- fn join_abs_path_home_dir(bh: &mut BenchHarness) {
- let posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.join("/home");
- });
- }
-
- #[bench]
- fn join_many_home_dir(bh: &mut BenchHarness) {
- let posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.join_many(&["home"]);
- });
- }
-
- #[bench]
- fn join_many_abs_path_home_dir(bh: &mut BenchHarness) {
- let posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.join_many(&["/home"]);
- });
- }
-
- #[bench]
- fn push_home_dir(bh: &mut BenchHarness) {
- let mut posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.push("home");
- });
- }
-
- #[bench]
- fn push_abs_path_home_dir(bh: &mut BenchHarness) {
- let mut posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.push("/home");
- });
- }
-
- #[bench]
- fn push_many_home_dir(bh: &mut BenchHarness) {
- let mut posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.push_many(&["home"]);
- });
- }
-
- #[bench]
- fn push_many_abs_path_home_dir(bh: &mut BenchHarness) {
- let mut posix_path = Path::new("/");
- bh.iter(|| {
- posix_path.push_many(&["/home"]);
- });
- }
-
- #[bench]
- fn ends_with_path_home_dir(bh: &mut BenchHarness) {
- let posix_home_path = Path::new("/home");
- bh.iter(|| {
- posix_home_path.ends_with_path(&Path::new("home"));
- });
- }
-
- #[bench]
- fn ends_with_path_missmatch_jome_home(bh: &mut BenchHarness) {
- let posix_home_path = Path::new("/home");
- bh.iter(|| {
- posix_home_path.ends_with_path(&Path::new("jome"));
- });
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Windows file path handling
-
-use ascii::AsciiCast;
-use c_str::{CString, ToCStr};
-use cast;
-use cmp::Eq;
-use from_str::FromStr;
-use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Invert, Iterator, Map};
-use option::{Option, Some, None};
-use str;
-use str::{CharSplitIterator, OwnedStr, Str, StrVector};
-use to_bytes::IterBytes;
-use vec::Vector;
-use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
-
-/// Iterator that yields successive components of a Path as &str
-///
-/// Each component is yielded as Option<&str> for compatibility with PosixPath, but
-/// every component in WindowsPath is guaranteed to be Some.
-pub type StrComponentIter<'self> = Map<'self, &'self str, Option<&'self str>,
- CharSplitIterator<'self, char>>;
-/// Iterator that yields components of a Path in reverse as &str
-///
-/// Each component is yielded as Option<&str> for compatibility with PosixPath, but
-/// every component in WindowsPath is guaranteed to be Some.
-pub type RevStrComponentIter<'self> = Invert<Map<'self, &'self str, Option<&'self str>,
- CharSplitIterator<'self, char>>>;
-
-/// Iterator that yields successive components of a Path as &[u8]
-pub type ComponentIter<'self> = Map<'self, Option<&'self str>, &'self [u8],
- StrComponentIter<'self>>;
-/// Iterator that yields components of a Path in reverse as &[u8]
-pub type RevComponentIter<'self> = Map<'self, Option<&'self str>, &'self [u8],
- RevStrComponentIter<'self>>;
-
-/// Represents a Windows path
-// Notes for Windows path impl:
-// The MAX_PATH is 260, but 253 is the practical limit due to some API bugs
-// See http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx for good information
-// about windows paths.
-// That same page puts a bunch of restrictions on allowed characters in a path.
-// `\foo.txt` means "relative to current drive", but will not be considered to be absolute here
-// as `∃P | P.join("\foo.txt") != "\foo.txt"`.
-// `C:` is interesting, that means "the current directory on drive C".
-// Long absolute paths need to have \\?\ prefix (or, for UNC, \\?\UNC\). I think that can be
-// ignored for now, though, and only added in a hypothetical .to_pwstr() function.
-// However, if a path is parsed that has \\?\, this needs to be preserved as it disables the
-// processing of "." and ".." components and / as a separator.
-// Experimentally, \\?\foo is not the same thing as \foo.
-// Also, \\foo is not valid either (certainly not equivalent to \foo).
-// Similarly, C:\\Users is not equivalent to C:\Users, although C:\Users\\foo is equivalent
-// to C:\Users\foo. In fact the command prompt treats C:\\foo\bar as UNC path. But it might be
-// best to just ignore that and normalize it to C:\foo\bar.
-//
-// Based on all this, I think the right approach is to do the following:
-// * Require valid utf-8 paths. Windows API may use WCHARs, but we don't, and utf-8 is convertible
-// to UTF-16 anyway (though does Windows use UTF-16 or UCS-2? Not sure).
-// * Parse the prefixes \\?\UNC\, \\?\, and \\.\ explicitly.
-// * If \\?\UNC\, treat following two path components as server\share. Don't error for missing
-// server\share.
-// * If \\?\, parse disk from following component, if present. Don't error for missing disk.
-// * If \\.\, treat rest of path as just regular components. I don't know how . and .. are handled
-// here, they probably aren't, but I'm not going to worry about that.
-// * Else if starts with \\, treat following two components as server\share. Don't error for missing
-// server\share.
-// * Otherwise, attempt to parse drive from start of path.
-//
-// The only error condition imposed here is valid utf-8. All other invalid paths are simply
-// preserved by the data structure; let the Windows API error out on them.
-#[deriving(Clone, DeepClone)]
-pub struct Path {
- priv repr: ~str, // assumed to never be empty
- priv prefix: Option<PathPrefix>,
- priv sepidx: Option<uint> // index of the final separator in the non-prefix portion of repr
-}
-
-impl Eq for Path {
- #[inline]
- fn eq(&self, other: &Path) -> bool {
- self.repr == other.repr
- }
-}
-
-impl FromStr for Path {
- fn from_str(s: &str) -> Option<Path> {
- Path::new_opt(s)
- }
-}
-
-impl ToCStr for Path {
- #[inline]
- fn to_c_str(&self) -> CString {
- // The Path impl guarantees no embedded NULs
- unsafe { self.as_vec().to_c_str_unchecked() }
- }
-
- #[inline]
- unsafe fn to_c_str_unchecked(&self) -> CString {
- self.as_vec().to_c_str_unchecked()
- }
-}
-
-impl IterBytes for Path {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: |&[u8]| -> bool) -> bool {
- self.repr.iter_bytes(lsb0, f)
- }
-}
-
-impl BytesContainer for Path {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_vec()
- }
- #[inline]
- fn container_into_owned_bytes(self) -> ~[u8] {
- self.into_vec()
- }
- #[inline]
- fn container_as_str<'a>(&'a self) -> &'a str {
- self.as_str().unwrap()
- }
- #[inline]
- fn container_as_str_opt<'a>(&'a self) -> Option<&'a str> {
- self.as_str()
- }
- #[inline]
- fn is_str(_: Option<Path>) -> bool { true }
-}
-
-impl<'self> BytesContainer for &'self Path {
- #[inline]
- fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
- self.as_vec()
- }
- #[inline]
- fn container_as_str<'a>(&'a self) -> &'a str {
- self.as_str().unwrap()
- }
- #[inline]
- fn container_as_str_opt<'a>(&'a self) -> Option<&'a str> {
- self.as_str()
- }
- #[inline]
- fn is_str(_: Option<&'self Path>) -> bool { true }
-}
-
-impl GenericPathUnsafe for Path {
- /// See `GenericPathUnsafe::from_vec_unchecked`.
- ///
- /// # Failure
- ///
- /// Raises the `str::not_utf8` condition if not valid UTF-8.
- #[inline]
- unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Path {
- let (prefix, path) = Path::normalize_(path.container_as_str());
- assert!(!path.is_empty());
- let mut ret = Path{ repr: path, prefix: prefix, sepidx: None };
- ret.update_sepidx();
- ret
- }
-
- /// See `GenericPathUnsafe::set_filename_unchecekd`.
- ///
- /// # Failure
- ///
- /// Raises the `str::not_utf8` condition if not valid UTF-8.
- unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
- let filename = filename.container_as_str();
- match self.sepidx_or_prefix_len() {
- None if ".." == self.repr => {
- let mut s = str::with_capacity(3 + filename.len());
- s.push_str("..");
- s.push_char(sep);
- s.push_str(filename);
- self.update_normalized(s);
- }
- None => {
- self.update_normalized(filename);
- }
- Some((_,idxa,end)) if self.repr.slice(idxa,end) == ".." => {
- let mut s = str::with_capacity(end + 1 + filename.len());
- s.push_str(self.repr.slice_to(end));
- s.push_char(sep);
- s.push_str(filename);
- self.update_normalized(s);
- }
- Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => {
- let mut s = str::with_capacity(idxb + filename.len());
- s.push_str(self.repr.slice_to(idxb));
- s.push_str(filename);
- self.update_normalized(s);
- }
- Some((idxb,_,_)) => {
- let mut s = str::with_capacity(idxb + 1 + filename.len());
- s.push_str(self.repr.slice_to(idxb));
- s.push_char(sep);
- s.push_str(filename);
- self.update_normalized(s);
- }
- }
- }
-
- /// See `GenericPathUnsafe::push_unchecked`.
- ///
- /// Concatenating two Windows Paths is rather complicated.
- /// For the most part, it will behave as expected, except in the case of
- /// pushing a volume-relative path, e.g. `C:foo.txt`. Because we have no
- /// concept of per-volume cwds like Windows does, we can't behave exactly
- /// like Windows will. Instead, if the receiver is an absolute path on
- /// the same volume as the new path, it will be treated as the cwd that
- /// the new path is relative to. Otherwise, the new path will be treated
- /// as if it were absolute and will replace the receiver outright.
- unsafe fn push_unchecked<T: BytesContainer>(&mut self, path: T) {
- let path = path.container_as_str();
- fn is_vol_abs(path: &str, prefix: Option<PathPrefix>) -> bool {
- // assume prefix is Some(DiskPrefix)
- let rest = path.slice_from(prefix_len(prefix));
- !rest.is_empty() && rest[0].is_ascii() && is_sep(rest[0] as char)
- }
- fn shares_volume(me: &Path, path: &str) -> bool {
- // path is assumed to have a prefix of Some(DiskPrefix)
- match me.prefix {
- Some(DiskPrefix) => me.repr[0] == path[0].to_ascii().to_upper().to_byte(),
- Some(VerbatimDiskPrefix) => me.repr[4] == path[0].to_ascii().to_upper().to_byte(),
- _ => false
- }
- }
- fn is_sep_(prefix: Option<PathPrefix>, u: u8) -> bool {
- if prefix_is_verbatim(prefix) { is_sep_verbatim(u as char) }
- else { is_sep(u as char) }
- }
-
- fn replace_path(me: &mut Path, path: &str, prefix: Option<PathPrefix>) {
- let newpath = Path::normalize__(path, prefix);
- me.repr = match newpath {
- Some(p) => p,
- None => path.to_owned()
- };
- me.prefix = prefix;
- me.update_sepidx();
- }
- fn append_path(me: &mut Path, path: &str) {
- // appends a path that has no prefix
- // if me is verbatim, we need to pre-normalize the new path
- let path_ = if is_verbatim(me) { Path::normalize__(path, None) }
- else { None };
- let pathlen = path_.as_ref().map_default(path.len(), |p| p.len());
- let mut s = str::with_capacity(me.repr.len() + 1 + pathlen);
- s.push_str(me.repr);
- let plen = me.prefix_len();
- if !(me.repr.len() > plen && me.repr[me.repr.len()-1] == sep as u8) {
- s.push_char(sep);
- }
- match path_ {
- None => s.push_str(path),
- Some(p) => s.push_str(p)
- };
- me.update_normalized(s)
- }
-
- if !path.is_empty() {
- let prefix = parse_prefix(path);
- match prefix {
- Some(DiskPrefix) if !is_vol_abs(path, prefix) && shares_volume(self, path) => {
- // cwd-relative path, self is on the same volume
- append_path(self, path.slice_from(prefix_len(prefix)));
- }
- Some(_) => {
- // absolute path, or cwd-relative and self is not same volume
- replace_path(self, path, prefix);
- }
- None if !path.is_empty() && is_sep_(self.prefix, path[0]) => {
- // volume-relative path
- if self.prefix.is_some() {
- // truncate self down to the prefix, then append
- let n = self.prefix_len();
- self.repr.truncate(n);
- append_path(self, path);
- } else {
- // we have no prefix, so nothing to be relative to
- replace_path(self, path, prefix);
- }
- }
- None => {
- // relative path
- append_path(self, path);
- }
- }
- }
- }
-}
-
-impl GenericPath for Path {
- #[inline]
- fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
- let s = path.container_as_str_opt();
- match s {
- None => None,
- Some(s) => {
- if contains_nul(s.as_bytes()) {
- None
- } else {
- Some(unsafe { GenericPathUnsafe::new_unchecked(s) })
- }
- }
- }
- }
-
- /// See `GenericPath::as_str` for info.
- /// Always returns a `Some` value.
- #[inline]
- fn as_str<'a>(&'a self) -> Option<&'a str> {
- Some(self.repr.as_slice())
- }
-
- #[inline]
- fn as_vec<'a>(&'a self) -> &'a [u8] {
- self.repr.as_bytes()
- }
-
- #[inline]
- fn into_vec(self) -> ~[u8] {
- self.repr.into_bytes()
- }
-
- #[inline]
- fn dirname<'a>(&'a self) -> &'a [u8] {
- self.dirname_str().unwrap().as_bytes()
- }
-
- /// See `GenericPath::dirname_str` for info.
- /// Always returns a `Some` value.
- fn dirname_str<'a>(&'a self) -> Option<&'a str> {
- Some(match self.sepidx_or_prefix_len() {
- None if ".." == self.repr => self.repr.as_slice(),
- None => ".",
- Some((_,idxa,end)) if self.repr.slice(idxa, end) == ".." => {
- self.repr.as_slice()
- }
- Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => {
- self.repr.as_slice()
- }
- Some((0,idxa,_)) => self.repr.slice_to(idxa),
- Some((idxb,idxa,_)) => {
- match self.prefix {
- Some(DiskPrefix) | Some(VerbatimDiskPrefix) if idxb == self.prefix_len() => {
- self.repr.slice_to(idxa)
- }
- _ => self.repr.slice_to(idxb)
- }
- }
- })
- }
-
- #[inline]
- fn filename<'a>(&'a self) -> Option<&'a [u8]> {
- self.filename_str().map(|x| x.as_bytes())
- }
-
- /// See `GenericPath::filename_str` for info.
- /// Always returns a `Some` value if `filename` returns a `Some` value.
- fn filename_str<'a>(&'a self) -> Option<&'a str> {
- match self.sepidx_or_prefix_len() {
- None if "." == self.repr || ".." == self.repr => None,
- None => Some(self.repr.as_slice()),
- Some((_,idxa,end)) if self.repr.slice(idxa, end) == ".." => None,
- Some((_,idxa,end)) if idxa == end => None,
- Some((_,idxa,end)) => Some(self.repr.slice(idxa, end))
- }
- }
-
- /// See `GenericPath::filestem_str` for info.
- /// Always returns a `Some` value if `filestem` returns a `Some` value.
- #[inline]
- fn filestem_str<'a>(&'a self) -> Option<&'a str> {
- // filestem() returns a byte vector that's guaranteed valid UTF-8
- self.filestem().map(cast::transmute)
- }
-
- #[inline]
- fn extension_str<'a>(&'a self) -> Option<&'a str> {
- // extension() returns a byte vector that's guaranteed valid UTF-8
- self.extension().map(cast::transmute)
- }
-
- fn dir_path(&self) -> Path {
- unsafe { GenericPathUnsafe::new_unchecked(self.dirname_str().unwrap()) }
- }
-
- #[inline]
- fn pop(&mut self) -> bool {
- match self.sepidx_or_prefix_len() {
- None if "." == self.repr => false,
- None => {
- self.repr = ~".";
- self.sepidx = None;
- true
- }
- Some((idxb,idxa,end)) if idxb == idxa && idxb == end => false,
- Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => false,
- Some((idxb,idxa,_)) => {
- let trunc = match self.prefix {
- Some(DiskPrefix) | Some(VerbatimDiskPrefix) | None => {
- let plen = self.prefix_len();
- if idxb == plen { idxa } else { idxb }
- }
- _ => idxb
- };
- self.repr.truncate(trunc);
- self.update_sepidx();
- true
- }
- }
- }
-
- fn root_path(&self) -> Option<Path> {
- if self.is_absolute() {
- Some(Path::new(match self.prefix {
- Some(VerbatimDiskPrefix)|Some(DiskPrefix) => {
- self.repr.slice_to(self.prefix_len()+1)
- }
- _ => self.repr.slice_to(self.prefix_len())
- }))
- } else if is_vol_relative(self) {
- Some(Path::new(self.repr.slice_to(1)))
- } else {
- None
- }
- }
-
- /// See `GenericPath::is_absolute` for info.
- ///
- /// A Windows Path is considered absolute only if it has a non-volume prefix,
- /// or if it has a volume prefix and the path starts with '\'.
- /// A path of `\foo` is not considered absolute because it's actually
- /// relative to the "current volume". A separate method `Path::is_vol_relative`
- /// is provided to indicate this case. Similarly a path of `C:foo` is not
- /// considered absolute because it's relative to the cwd on volume C:. A
- /// separate method `Path::is_cwd_relative` is provided to indicate this case.
- #[inline]
- fn is_absolute(&self) -> bool {
- match self.prefix {
- Some(DiskPrefix) => {
- let rest = self.repr.slice_from(self.prefix_len());
- rest.len() > 0 && rest[0] == sep as u8
- }
- Some(_) => true,
- None => false
- }
- }
-
- #[inline]
- fn is_relative(&self) -> bool {
- self.prefix.is_none() && !is_vol_relative(self)
- }
-
- fn is_ancestor_of(&self, other: &Path) -> bool {
- if !self.equiv_prefix(other) {
- false
- } else if self.is_absolute() != other.is_absolute() ||
- is_vol_relative(self) != is_vol_relative(other) {
- false
- } else {
- let mut ita = self.str_components().map(|x|x.unwrap());
- let mut itb = other.str_components().map(|x|x.unwrap());
- if "." == self.repr {
- return itb.next() != Some("..");
- }
- loop {
- match (ita.next(), itb.next()) {
- (None, _) => break,
- (Some(a), Some(b)) if a == b => { continue },
- (Some(a), _) if a == ".." => {
- // if ita contains only .. components, it's an ancestor
- return ita.all(|x| x == "..");
- }
- _ => return false
- }
- }
- true
- }
- }
-
- fn path_relative_from(&self, base: &Path) -> Option<Path> {
- fn comp_requires_verbatim(s: &str) -> bool {
- s == "." || s == ".." || s.contains_char(sep2)
- }
-
- if !self.equiv_prefix(base) {
- // prefixes differ
- if self.is_absolute() {
- Some(self.clone())
- } else if self.prefix == Some(DiskPrefix) && base.prefix == Some(DiskPrefix) {
- // both drives, drive letters must differ or they'd be equiv
- Some(self.clone())
- } else {
- None
- }
- } else if self.is_absolute() != base.is_absolute() {
- if self.is_absolute() {
- Some(self.clone())
- } else {
- None
- }
- } else if is_vol_relative(self) != is_vol_relative(base) {
- if is_vol_relative(self) {
- Some(self.clone())
- } else {
- None
- }
- } else {
- let mut ita = self.str_components().map(|x|x.unwrap());
- let mut itb = base.str_components().map(|x|x.unwrap());
- let mut comps = ~[];
-
- let a_verb = is_verbatim(self);
- let b_verb = is_verbatim(base);
- loop {
- match (ita.next(), itb.next()) {
- (None, None) => break,
- (Some(a), None) if a_verb && comp_requires_verbatim(a) => {
- return Some(self.clone())
- }
- (Some(a), None) => {
- comps.push(a);
- if !a_verb {
- comps.extend(&mut ita);
- break;
- }
- }
- (None, _) => comps.push(".."),
- (Some(a), Some(b)) if comps.is_empty() && a == b => (),
- (Some(a), Some(b)) if !b_verb && b == "." => {
- if a_verb && comp_requires_verbatim(a) {
- return Some(self.clone())
- } else { comps.push(a) }
- }
- (Some(_), Some(b)) if !b_verb && b == ".." => return None,
- (Some(a), Some(_)) if a_verb && comp_requires_verbatim(a) => {
- return Some(self.clone())
- }
- (Some(a), Some(_)) => {
- comps.push("..");
- for _ in itb {
- comps.push("..");
- }
- comps.push(a);
- if !a_verb {
- comps.extend(&mut ita);
- break;
- }
- }
- }
- }
- Some(Path::new(comps.connect("\\")))
- }
- }
-
- fn ends_with_path(&self, child: &Path) -> bool {
- if !child.is_relative() { return false; }
- let mut selfit = self.str_components().invert();
- let mut childit = child.str_components().invert();
- loop {
- match (selfit.next(), childit.next()) {
- (Some(a), Some(b)) => if a != b { return false; },
- (Some(_), None) => break,
- (None, Some(_)) => return false,
- (None, None) => break
- }
- }
- true
- }
-}
-
-impl Path {
- /// Returns a new Path from a byte vector or string
- ///
- /// # Failure
- ///
- /// Raises the `null_byte` condition if the vector contains a NUL.
- /// Raises the `str::not_utf8` condition if invalid UTF-8.
- #[inline]
- pub fn new<T: BytesContainer>(path: T) -> Path {
- GenericPath::new(path)
- }
-
- /// Returns a new Path from a byte vector or string, if possible
- #[inline]
- pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
- GenericPath::new_opt(path)
- }
-
- /// Returns an iterator that yields each component of the path in turn as a Option<&str>.
- /// Every component is guaranteed to be Some.
- /// Does not yield the path prefix (including server/share components in UNC paths).
- /// Does not distinguish between volume-relative and relative paths, e.g.
- /// \a\b\c and a\b\c.
- /// Does not distinguish between absolute and cwd-relative paths, e.g.
- /// C:\foo and C:foo.
- pub fn str_components<'a>(&'a self) -> StrComponentIter<'a> {
- let s = match self.prefix {
- Some(_) => {
- let plen = self.prefix_len();
- if self.repr.len() > plen && self.repr[plen] == sep as u8 {
- self.repr.slice_from(plen+1)
- } else { self.repr.slice_from(plen) }
- }
- None if self.repr[0] == sep as u8 => self.repr.slice_from(1),
- None => self.repr.as_slice()
- };
- let ret = s.split_terminator(sep).map(Some);
- ret
- }
-
- /// Returns an iterator that yields each component of the path in reverse as an Option<&str>
- /// See str_components() for details.
- pub fn rev_str_components<'a>(&'a self) -> RevStrComponentIter<'a> {
- self.str_components().invert()
- }
-
- /// Returns an iterator that yields each component of the path in turn as a &[u8].
- /// See str_components() for details.
- pub fn components<'a>(&'a self) -> ComponentIter<'a> {
- fn convert<'a>(x: Option<&'a str>) -> &'a [u8] {
- #[inline];
- x.unwrap().as_bytes()
- }
- self.str_components().map(convert)
- }
-
- /// Returns an iterator that yields each component of the path in reverse as a &[u8].
- /// See str_components() for details.
- pub fn rev_components<'a>(&'a self) -> RevComponentIter<'a> {
- fn convert<'a>(x: Option<&'a str>) -> &'a [u8] {
- #[inline];
- x.unwrap().as_bytes()
- }
- self.rev_str_components().map(convert)
- }
-
- fn equiv_prefix(&self, other: &Path) -> bool {
- match (self.prefix, other.prefix) {
- (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => {
- self.is_absolute() &&
- self.repr[0].to_ascii().eq_ignore_case(other.repr[4].to_ascii())
- }
- (Some(VerbatimDiskPrefix), Some(DiskPrefix)) => {
- other.is_absolute() &&
- self.repr[4].to_ascii().eq_ignore_case(other.repr[0].to_ascii())
- }
- (Some(VerbatimDiskPrefix), Some(VerbatimDiskPrefix)) => {
- self.repr[4].to_ascii().eq_ignore_case(other.repr[4].to_ascii())
- }
- (Some(UNCPrefix(_,_)), Some(VerbatimUNCPrefix(_,_))) => {
- self.repr.slice(2, self.prefix_len()) == other.repr.slice(8, other.prefix_len())
- }
- (Some(VerbatimUNCPrefix(_,_)), Some(UNCPrefix(_,_))) => {
- self.repr.slice(8, self.prefix_len()) == other.repr.slice(2, other.prefix_len())
- }
- (None, None) => true,
- (a, b) if a == b => {
- self.repr.slice_to(self.prefix_len()) == other.repr.slice_to(other.prefix_len())
- }
- _ => false
- }
- }
-
- fn normalize_<S: Str>(s: S) -> (Option<PathPrefix>, ~str) {
- // make borrowck happy
- let (prefix, val) = {
- let prefix = parse_prefix(s.as_slice());
- let path = Path::normalize__(s.as_slice(), prefix);
- (prefix, path)
- };
- (prefix, match val {
- None => s.into_owned(),
- Some(val) => val
- })
- }
-
- fn normalize__(s: &str, prefix: Option<PathPrefix>) -> Option<~str> {
- if prefix_is_verbatim(prefix) {
- // don't do any normalization
- match prefix {
- Some(VerbatimUNCPrefix(x, 0)) if s.len() == 8 + x => {
- // the server component has no trailing '\'
- let mut s = s.into_owned();
- s.push_char(sep);
- Some(s)
- }
- _ => None
- }
- } else {
- let (is_abs, comps) = normalize_helper(s, prefix);
- let mut comps = comps;
- match (comps.is_some(),prefix) {
- (false, Some(DiskPrefix)) => {
- if s[0] >= 'a' as u8 && s[0] <= 'z' as u8 {
- comps = Some(~[]);
- }
- }
- (false, Some(VerbatimDiskPrefix)) => {
- if s[4] >= 'a' as u8 && s[0] <= 'z' as u8 {
- comps = Some(~[]);
- }
- }
- _ => ()
- }
- match comps {
- None => None,
- Some(comps) => {
- if prefix.is_some() && comps.is_empty() {
- match prefix.unwrap() {
- DiskPrefix => {
- let len = prefix_len(prefix) + is_abs as uint;
- let mut s = s.slice_to(len).to_owned();
- unsafe {
- str::raw::as_owned_vec(&mut s)[0] =
- s[0].to_ascii().to_upper().to_byte();
- }
- if is_abs {
- // normalize C:/ to C:\
- unsafe {
- str::raw::as_owned_vec(&mut s)[2] = sep as u8;
- }
- }
- Some(s)
- }
- VerbatimDiskPrefix => {
- let len = prefix_len(prefix) + is_abs as uint;
- let mut s = s.slice_to(len).to_owned();
- unsafe {
- str::raw::as_owned_vec(&mut s)[4] =
- s[4].to_ascii().to_upper().to_byte();
- }
- Some(s)
- }
- _ => {
- let plen = prefix_len(prefix);
- if s.len() > plen {
- Some(s.slice_to(plen).to_owned())
- } else { None }
- }
- }
- } else if is_abs && comps.is_empty() {
- Some(str::from_char(sep))
- } else {
- let prefix_ = s.slice_to(prefix_len(prefix));
- let n = prefix_.len() +
- if is_abs { comps.len() } else { comps.len() - 1} +
- comps.iter().map(|v| v.len()).sum();
- let mut s = str::with_capacity(n);
- match prefix {
- Some(DiskPrefix) => {
- s.push_char(prefix_[0].to_ascii().to_upper().to_char());
- s.push_char(':');
- }
- Some(VerbatimDiskPrefix) => {
- s.push_str(prefix_.slice_to(4));
- s.push_char(prefix_[4].to_ascii().to_upper().to_char());
- s.push_str(prefix_.slice_from(5));
- }
- Some(UNCPrefix(a,b)) => {
- s.push_str("\\\\");
- s.push_str(prefix_.slice(2, a+2));
- s.push_char(sep);
- s.push_str(prefix_.slice(3+a, 3+a+b));
- }
- Some(_) => s.push_str(prefix_),
- None => ()
- }
- let mut it = comps.move_iter();
- if !is_abs {
- match it.next() {
- None => (),
- Some(comp) => s.push_str(comp)
- }
- }
- for comp in it {
- s.push_char(sep);
- s.push_str(comp);
- }
- Some(s)
- }
- }
- }
- }
- }
-
- fn update_sepidx(&mut self) {
- let s = if self.has_nonsemantic_trailing_slash() {
- self.repr.slice_to(self.repr.len()-1)
- } else { self.repr.as_slice() };
- let idx = s.rfind(if !prefix_is_verbatim(self.prefix) { is_sep }
- else { is_sep_verbatim });
- let prefixlen = self.prefix_len();
- self.sepidx = idx.and_then(|x| if x < prefixlen { None } else { Some(x) });
- }
-
- fn prefix_len(&self) -> uint {
- prefix_len(self.prefix)
- }
-
- // Returns a tuple (before, after, end) where before is the index of the separator
- // and after is the index just after the separator.
- // end is the length of the string, normally, or the index of the final character if it is
- // a non-semantic trailing separator in a verbatim string.
- // If the prefix is considered the separator, before and after are the same.
- fn sepidx_or_prefix_len(&self) -> Option<(uint,uint,uint)> {
- match self.sepidx {
- None => match self.prefix_len() { 0 => None, x => Some((x,x,self.repr.len())) },
- Some(x) => {
- if self.has_nonsemantic_trailing_slash() {
- Some((x,x+1,self.repr.len()-1))
- } else { Some((x,x+1,self.repr.len())) }
- }
- }
- }
-
- fn has_nonsemantic_trailing_slash(&self) -> bool {
- is_verbatim(self) && self.repr.len() > self.prefix_len()+1 &&
- self.repr[self.repr.len()-1] == sep as u8
- }
-
- fn update_normalized<S: Str>(&mut self, s: S) {
- let (prefix, path) = Path::normalize_(s);
- self.repr = path;
- self.prefix = prefix;
- self.update_sepidx();
- }
-}
-
-/// Returns whether the path is considered "volume-relative", which means a path
-/// that looks like "\foo". Paths of this form are relative to the current volume,
-/// but absolute within that volume.
-#[inline]
-pub fn is_vol_relative(path: &Path) -> bool {
- path.prefix.is_none() && is_sep_byte(&path.repr[0])
-}
-
-/// Returns whether the path is considered "cwd-relative", which means a path
-/// with a volume prefix that is not absolute. This look like "C:foo.txt". Paths
-/// of this form are relative to the cwd on the given volume.
-#[inline]
-pub fn is_cwd_relative(path: &Path) -> bool {
- path.prefix == Some(DiskPrefix) && !path.is_absolute()
-}
-
-/// Returns the PathPrefix for this Path
-#[inline]
-pub fn prefix(path: &Path) -> Option<PathPrefix> {
- path.prefix
-}
-
-/// Returns whether the Path's prefix is a verbatim prefix, i.e. \\?\
-#[inline]
-pub fn is_verbatim(path: &Path) -> bool {
- prefix_is_verbatim(path.prefix)
-}
-
-/// The standard path separator character
-pub static sep: char = '\\';
-/// The alternative path separator character
-pub static sep2: char = '/';
-
-/// Returns whether the given char is a path separator.
-/// Allows both the primary separator '\' and the alternative separator '/'.
-#[inline]
-pub fn is_sep(c: char) -> bool {
- c == sep || c == sep2
-}
-
-/// Returns whether the given char is a path separator.
-/// Only allows the primary separator '\'; use is_sep to allow '/'.
-#[inline]
-pub fn is_sep_verbatim(c: char) -> bool {
- c == sep
-}
-
-/// Returns whether the given byte is a path separator.
-/// Allows both the primary separator '\' and the alternative separator '/'.
-#[inline]
-pub fn is_sep_byte(u: &u8) -> bool {
- *u as char == sep || *u as char == sep2
-}
-
-/// Returns whether the given byte is a path separator.
-/// Only allows the primary separator '\'; use is_sep_byte to allow '/'.
-#[inline]
-pub fn is_sep_byte_verbatim(u: &u8) -> bool {
- *u as char == sep
-}
-
-/// Prefix types for Path
-#[deriving(Eq, Clone, DeepClone)]
-pub enum PathPrefix {
- /// Prefix `\\?\`, uint is the length of the following component
- VerbatimPrefix(uint),
- /// Prefix `\\?\UNC\`, uints are the lengths of the UNC components
- VerbatimUNCPrefix(uint, uint),
- /// Prefix `\\?\C:\` (for any alphabetic character)
- VerbatimDiskPrefix,
- /// Prefix `\\.\`, uint is the length of the following component
- DeviceNSPrefix(uint),
- /// UNC prefix `\\server\share`, uints are the lengths of the server/share
- UNCPrefix(uint, uint),
- /// Prefix `C:` for any alphabetic character
- DiskPrefix
-}
-
-// FIXME (#8169): Make private once visibility is fixed
-fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
- if path.starts_with("\\\\") {
- // \\
- path = path.slice_from(2);
- if path.starts_with("?\\") {
- // \\?\
- path = path.slice_from(2);
- if path.starts_with("UNC\\") {
- // \\?\UNC\server\share
- path = path.slice_from(4);
- let (idx_a, idx_b) = match parse_two_comps(path, is_sep_verbatim) {
- Some(x) => x,
- None => (path.len(), 0)
- };
- return Some(VerbatimUNCPrefix(idx_a, idx_b));
- } else {
- // \\?\path
- let idx = path.find('\\');
- if idx == Some(2) && path[1] == ':' as u8 {
- let c = path[0];
- if c.is_ascii() && ::char::is_alphabetic(c as char) {
- // \\?\C:\ path
- return Some(VerbatimDiskPrefix);
- }
- }
- let idx = idx.unwrap_or(path.len());
- return Some(VerbatimPrefix(idx));
- }
- } else if path.starts_with(".\\") {
- // \\.\path
- path = path.slice_from(2);
- let idx = path.find('\\').unwrap_or(path.len());
- return Some(DeviceNSPrefix(idx));
- }
- match parse_two_comps(path, is_sep) {
- Some((idx_a, idx_b)) if idx_a > 0 && idx_b > 0 => {
- // \\server\share
- return Some(UNCPrefix(idx_a, idx_b));
- }
- _ => ()
- }
- } else if path.len() > 1 && path[1] == ':' as u8 {
- // C:
- let c = path[0];
- if c.is_ascii() && ::char::is_alphabetic(c as char) {
- return Some(DiskPrefix);
- }
- }
- return None;
-
- fn parse_two_comps<'a>(mut path: &'a str, f: |char| -> bool)
- -> Option<(uint, uint)> {
- let idx_a = match path.find(|x| f(x)) {
- None => return None,
- Some(x) => x
- };
- path = path.slice_from(idx_a+1);
- let idx_b = path.find(f).unwrap_or(path.len());
- Some((idx_a, idx_b))
- }
-}
-
-// None result means the string didn't need normalizing
-fn normalize_helper<'a>(s: &'a str, prefix: Option<PathPrefix>) -> (bool,Option<~[&'a str]>) {
- let f = if !prefix_is_verbatim(prefix) { is_sep } else { is_sep_verbatim };
- let is_abs = s.len() > prefix_len(prefix) && f(s.char_at(prefix_len(prefix)));
- let s_ = s.slice_from(prefix_len(prefix));
- let s_ = if is_abs { s_.slice_from(1) } else { s_ };
-
- if is_abs && s_.is_empty() {
- return (is_abs, match prefix {
- Some(DiskPrefix) | None => (if is_sep_verbatim(s.char_at(prefix_len(prefix))) { None }
- else { Some(~[]) }),
- Some(_) => Some(~[]), // need to trim the trailing separator
- });
- }
- let mut comps: ~[&'a str] = ~[];
- let mut n_up = 0u;
- let mut changed = false;
- for comp in s_.split(f) {
- if comp.is_empty() { changed = true }
- else if comp == "." { changed = true }
- else if comp == ".." {
- let has_abs_prefix = match prefix {
- Some(DiskPrefix) => false,
- Some(_) => true,
- None => false
- };
- if (is_abs || has_abs_prefix) && comps.is_empty() { changed = true }
- else if comps.len() == n_up { comps.push(".."); n_up += 1 }
- else { comps.pop(); changed = true }
- } else { comps.push(comp) }
- }
- if !changed && !prefix_is_verbatim(prefix) {
- changed = s.find(is_sep).is_some();
- }
- if changed {
- if comps.is_empty() && !is_abs && prefix.is_none() {
- if s == "." {
- return (is_abs, None);
- }
- comps.push(".");
- }
- (is_abs, Some(comps))
- } else {
- (is_abs, None)
- }
-}
-
-fn prefix_is_verbatim(p: Option<PathPrefix>) -> bool {
- match p {
- Some(VerbatimPrefix(_)) | Some(VerbatimUNCPrefix(_,_)) | Some(VerbatimDiskPrefix) => true,
- Some(DeviceNSPrefix(_)) => true, // not really sure, but I think so
- _ => false
- }
-}
-
-fn prefix_len(p: Option<PathPrefix>) -> uint {
- match p {
- None => 0,
- Some(VerbatimPrefix(x)) => 4 + x,
- Some(VerbatimUNCPrefix(x,y)) => 8 + x + 1 + y,
- Some(VerbatimDiskPrefix) => 6,
- Some(UNCPrefix(x,y)) => 2 + x + 1 + y,
- Some(DeviceNSPrefix(x)) => 4 + x,
- Some(DiskPrefix) => 2
- }
-}
-
-fn prefix_is_sep(p: Option<PathPrefix>, c: u8) -> bool {
- c.is_ascii() && if !prefix_is_verbatim(p) { is_sep(c as char) }
- else { is_sep_verbatim(c as char) }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use super::parse_prefix;
- use option::{Some,None};
- use iter::Iterator;
- use vec::Vector;
-
- macro_rules! t(
- (s: $path:expr, $exp:expr) => (
- {
- let path = $path;
- assert_eq!(path.as_str(), Some($exp));
- }
- );
- (v: $path:expr, $exp:expr) => (
- {
- let path = $path;
- assert_eq!(path.as_vec(), $exp);
- }
- )
- )
-
- macro_rules! b(
- ($($arg:expr),+) => (
- bytes!($($arg),+)
- )
- )
-
- #[test]
- fn test_parse_prefix() {
- macro_rules! t(
- ($path:expr, $exp:expr) => (
- {
- let path = $path;
- let exp = $exp;
- let res = parse_prefix(path);
- assert!(res == exp,
- "parse_prefix(\"{}\"): expected {:?}, found {:?}", path, exp, res);
- }
- )
- )
-
- t!("\\\\SERVER\\share\\foo", Some(UNCPrefix(6,5)));
- t!("\\\\", None);
- t!("\\\\SERVER", None);
- t!("\\\\SERVER\\", None);
- t!("\\\\SERVER\\\\", None);
- t!("\\\\SERVER\\\\foo", None);
- t!("\\\\SERVER\\share", Some(UNCPrefix(6,5)));
- t!("\\\\SERVER/share/foo", Some(UNCPrefix(6,5)));
- t!("\\\\SERVER\\share/foo", Some(UNCPrefix(6,5)));
- t!("//SERVER/share/foo", None);
- t!("\\\\\\a\\b\\c", None);
- t!("\\\\?\\a\\b\\c", Some(VerbatimPrefix(1)));
- t!("\\\\?\\a/b/c", Some(VerbatimPrefix(5)));
- t!("//?/a/b/c", None);
- t!("\\\\.\\a\\b", Some(DeviceNSPrefix(1)));
- t!("\\\\.\\a/b", Some(DeviceNSPrefix(3)));
- t!("//./a/b", None);
- t!("\\\\?\\UNC\\server\\share\\foo", Some(VerbatimUNCPrefix(6,5)));
- t!("\\\\?\\UNC\\\\share\\foo", Some(VerbatimUNCPrefix(0,5)));
- t!("\\\\?\\UNC\\", Some(VerbatimUNCPrefix(0,0)));
- t!("\\\\?\\UNC\\server/share/foo", Some(VerbatimUNCPrefix(16,0)));
- t!("\\\\?\\UNC\\server", Some(VerbatimUNCPrefix(6,0)));
- t!("\\\\?\\UNC\\server\\", Some(VerbatimUNCPrefix(6,0)));
- t!("\\\\?\\UNC/server/share", Some(VerbatimPrefix(16)));
- t!("\\\\?\\UNC", Some(VerbatimPrefix(3)));
- t!("\\\\?\\C:\\a\\b.txt", Some(VerbatimDiskPrefix));
- t!("\\\\?\\z:\\", Some(VerbatimDiskPrefix));
- t!("\\\\?\\C:", Some(VerbatimPrefix(2)));
- t!("\\\\?\\C:a.txt", Some(VerbatimPrefix(7)));
- t!("\\\\?\\C:a\\b.txt", Some(VerbatimPrefix(3)));
- t!("\\\\?\\C:/a", Some(VerbatimPrefix(4)));
- t!("C:\\foo", Some(DiskPrefix));
- t!("z:/foo", Some(DiskPrefix));
- t!("d:", Some(DiskPrefix));
- t!("ab:", None);
- t!("ü:\\foo", None);
- t!("3:\\foo", None);
- t!(" :\\foo", None);
- t!("::\\foo", None);
- t!("\\\\?\\C:", Some(VerbatimPrefix(2)));
- t!("\\\\?\\z:\\", Some(VerbatimDiskPrefix));
- t!("\\\\?\\ab:\\", Some(VerbatimPrefix(3)));
- t!("\\\\?\\C:\\a", Some(VerbatimDiskPrefix));
- t!("\\\\?\\C:/a", Some(VerbatimPrefix(4)));
- t!("\\\\?\\C:\\a/b", Some(VerbatimDiskPrefix));
- }
-
- #[test]
- fn test_paths() {
- let empty: &[u8] = [];
- t!(v: Path::new(empty), b!("."));
- t!(v: Path::new(b!("\\")), b!("\\"));
- t!(v: Path::new(b!("a\\b\\c")), b!("a\\b\\c"));
-
- t!(s: Path::new(""), ".");
- t!(s: Path::new("\\"), "\\");
- t!(s: Path::new("hi"), "hi");
- t!(s: Path::new("hi\\"), "hi");
- t!(s: Path::new("\\lib"), "\\lib");
- t!(s: Path::new("\\lib\\"), "\\lib");
- t!(s: Path::new("hi\\there"), "hi\\there");
- t!(s: Path::new("hi\\there.txt"), "hi\\there.txt");
- t!(s: Path::new("/"), "\\");
- t!(s: Path::new("hi/"), "hi");
- t!(s: Path::new("/lib"), "\\lib");
- t!(s: Path::new("/lib/"), "\\lib");
- t!(s: Path::new("hi/there"), "hi\\there");
-
- t!(s: Path::new("hi\\there\\"), "hi\\there");
- t!(s: Path::new("hi\\..\\there"), "there");
- t!(s: Path::new("hi/../there"), "there");
- t!(s: Path::new("..\\hi\\there"), "..\\hi\\there");
- t!(s: Path::new("\\..\\hi\\there"), "\\hi\\there");
- t!(s: Path::new("/../hi/there"), "\\hi\\there");
- t!(s: Path::new("foo\\.."), ".");
- t!(s: Path::new("\\foo\\.."), "\\");
- t!(s: Path::new("\\foo\\..\\.."), "\\");
- t!(s: Path::new("\\foo\\..\\..\\bar"), "\\bar");
- t!(s: Path::new("\\.\\hi\\.\\there\\."), "\\hi\\there");
- t!(s: Path::new("\\.\\hi\\.\\there\\.\\.."), "\\hi");
- t!(s: Path::new("foo\\..\\.."), "..");
- t!(s: Path::new("foo\\..\\..\\.."), "..\\..");
- t!(s: Path::new("foo\\..\\..\\bar"), "..\\bar");
-
- assert_eq!(Path::new(b!("foo\\bar")).into_vec(), b!("foo\\bar").to_owned());
- assert_eq!(Path::new(b!("\\foo\\..\\..\\bar")).into_vec(),
- b!("\\bar").to_owned());
-
- t!(s: Path::new("\\\\a"), "\\a");
- t!(s: Path::new("\\\\a\\"), "\\a");
- t!(s: Path::new("\\\\a\\b"), "\\\\a\\b");
- t!(s: Path::new("\\\\a\\b\\"), "\\\\a\\b");
- t!(s: Path::new("\\\\a\\b/"), "\\\\a\\b");
- t!(s: Path::new("\\\\\\b"), "\\b");
- t!(s: Path::new("\\\\a\\\\b"), "\\a\\b");
- t!(s: Path::new("\\\\a\\b\\c"), "\\\\a\\b\\c");
- t!(s: Path::new("\\\\server\\share/path"), "\\\\server\\share\\path");
- t!(s: Path::new("\\\\server/share/path"), "\\\\server\\share\\path");
- t!(s: Path::new("C:a\\b.txt"), "C:a\\b.txt");
- t!(s: Path::new("C:a/b.txt"), "C:a\\b.txt");
- t!(s: Path::new("z:\\a\\b.txt"), "Z:\\a\\b.txt");
- t!(s: Path::new("z:/a/b.txt"), "Z:\\a\\b.txt");
- t!(s: Path::new("ab:/a/b.txt"), "ab:\\a\\b.txt");
- t!(s: Path::new("C:\\"), "C:\\");
- t!(s: Path::new("C:"), "C:");
- t!(s: Path::new("q:"), "Q:");
- t!(s: Path::new("C:/"), "C:\\");
- t!(s: Path::new("C:\\foo\\.."), "C:\\");
- t!(s: Path::new("C:foo\\.."), "C:");
- t!(s: Path::new("C:\\a\\"), "C:\\a");
- t!(s: Path::new("C:\\a/"), "C:\\a");
- t!(s: Path::new("C:\\a\\b\\"), "C:\\a\\b");
- t!(s: Path::new("C:\\a\\b/"), "C:\\a\\b");
- t!(s: Path::new("C:a\\"), "C:a");
- t!(s: Path::new("C:a/"), "C:a");
- t!(s: Path::new("C:a\\b\\"), "C:a\\b");
- t!(s: Path::new("C:a\\b/"), "C:a\\b");
- t!(s: Path::new("\\\\?\\z:\\a\\b.txt"), "\\\\?\\z:\\a\\b.txt");
- t!(s: Path::new("\\\\?\\C:/a/b.txt"), "\\\\?\\C:/a/b.txt");
- t!(s: Path::new("\\\\?\\C:\\a/b.txt"), "\\\\?\\C:\\a/b.txt");
- t!(s: Path::new("\\\\?\\test\\a\\b.txt"), "\\\\?\\test\\a\\b.txt");
- t!(s: Path::new("\\\\?\\foo\\bar\\"), "\\\\?\\foo\\bar\\");
- t!(s: Path::new("\\\\.\\foo\\bar"), "\\\\.\\foo\\bar");
- t!(s: Path::new("\\\\.\\"), "\\\\.\\");
- t!(s: Path::new("\\\\?\\UNC\\server\\share\\foo"), "\\\\?\\UNC\\server\\share\\foo");
- t!(s: Path::new("\\\\?\\UNC\\server/share"), "\\\\?\\UNC\\server/share\\");
- t!(s: Path::new("\\\\?\\UNC\\server"), "\\\\?\\UNC\\server\\");
- t!(s: Path::new("\\\\?\\UNC\\"), "\\\\?\\UNC\\\\");
- t!(s: Path::new("\\\\?\\UNC"), "\\\\?\\UNC");
-
- // I'm not sure whether \\.\foo/bar should normalize to \\.\foo\bar
- // as information is sparse and this isn't really googleable.
- // I'm going to err on the side of not normalizing it, as this skips the filesystem
- t!(s: Path::new("\\\\.\\foo/bar"), "\\\\.\\foo/bar");
- t!(s: Path::new("\\\\.\\foo\\bar"), "\\\\.\\foo\\bar");
- }
-
- #[test]
- fn test_opt_paths() {
- assert_eq!(Path::new_opt(b!("foo\\bar", 0)), None);
- assert_eq!(Path::new_opt(b!("foo\\bar", 0x80)), None);
- t!(v: Path::new_opt(b!("foo\\bar")).unwrap(), b!("foo\\bar"));
- assert_eq!(Path::new_opt("foo\\bar\0"), None);
- t!(s: Path::new_opt("foo\\bar").unwrap(), "foo\\bar");
- }
-
- #[test]
- fn test_null_byte() {
- use path::null_byte::cond;
-
- let mut handled = false;
- let mut p = cond.trap(|v| {
- handled = true;
- assert_eq!(v.as_slice(), b!("foo\\bar", 0));
- (b!("\\bar").to_owned())
- }).inside(|| {
- Path::new(b!("foo\\bar", 0))
- });
- assert!(handled);
- assert_eq!(p.as_vec(), b!("\\bar"));
-
- handled = false;
- cond.trap(|v| {
- handled = true;
- assert_eq!(v.as_slice(), b!("f", 0, "o"));
- (b!("foo").to_owned())
- }).inside(|| {
- p.set_filename(b!("f", 0, "o"))
- });
- assert!(handled);
- assert_eq!(p.as_vec(), b!("\\foo"));
-
- handled = false;
- cond.trap(|v| {
- handled = true;
- assert_eq!(v.as_slice(), b!("f", 0, "o"));
- (b!("foo").to_owned())
- }).inside(|| {
- p.push(b!("f", 0, "o"));
- });
- assert!(handled);
- assert_eq!(p.as_vec(), b!("\\foo\\foo"));
- }
-
- #[test]
- fn test_null_byte_fail() {
- use path::null_byte::cond;
- use task;
-
- macro_rules! t(
- ($name:expr => $code:block) => (
- {
- let mut t = task::task();
- t.name($name);
- let res = do t.try $code;
- assert!(res.is_err());
- }
- )
- )
-
- t!(~"from_vec() w\\nul" => {
- cond.trap(|_| {
- (b!("null", 0).to_owned())
- }).inside(|| {
- Path::new(b!("foo\\bar", 0))
- });
- })
-
- t!(~"set_filename w\\nul" => {
- let mut p = Path::new(b!("foo\\bar"));
- cond.trap(|_| {
- (b!("null", 0).to_owned())
- }).inside(|| {
- p.set_filename(b!("foo", 0))
- });
- })
-
- t!(~"push w\\nul" => {
- let mut p = Path::new(b!("foo\\bar"));
- cond.trap(|_| {
- (b!("null", 0).to_owned())
- }).inside(|| {
- p.push(b!("foo", 0))
- });
- })
- }
-
- #[test]
- #[should_fail]
- fn test_not_utf8_fail() {
- Path::new(b!("hello", 0x80, ".txt"));
- }
-
- #[test]
- fn test_display_str() {
- let path = Path::new("foo");
- assert_eq!(path.display().to_str(), ~"foo");
- let path = Path::new(b!("\\"));
- assert_eq!(path.filename_display().to_str(), ~"");
-
- let mut called = false;
- let path = Path::new("foo");
- path.display().with_str(|s| {
- assert_eq!(s, "foo");
- called = true;
- });
- assert!(called);
- called = false;
- let path = Path::new(b!("\\"));
- path.filename_display().with_str(|s| {
- assert_eq!(s, "");
- called = true;
- });
- assert!(called);
- }
-
- #[test]
- fn test_display() {
- macro_rules! t(
- ($path:expr, $exp:expr, $expf:expr) => (
- {
- let path = Path::new($path);
- let f = format!("{}", path.display());
- assert_eq!(f.as_slice(), $exp);
- let f = format!("{}", path.filename_display());
- assert_eq!(f.as_slice(), $expf);
- }
- )
- )
-
- t!("foo", "foo", "foo");
- t!("foo\\bar", "foo\\bar", "bar");
- t!("\\", "\\", "");
- }
-
- #[test]
- fn test_components() {
- macro_rules! t(
- (s: $path:expr, $op:ident, $exp:expr) => (
- {
- let path = Path::new($path);
- assert_eq!(path.$op(), Some($exp));
- }
- );
- (s: $path:expr, $op:ident, $exp:expr, opt) => (
- {
- let path = Path::new($path);
- let left = path.$op();
- assert_eq!(left, $exp);
- }
- );
- (v: $path:expr, $op:ident, $exp:expr) => (
- {
- let path = Path::new($path);
- assert_eq!(path.$op(), $exp);
- }
- )
- )
-
- t!(v: b!("a\\b\\c"), filename, Some(b!("c")));
- t!(s: "a\\b\\c", filename_str, "c");
- t!(s: "\\a\\b\\c", filename_str, "c");
- t!(s: "a", filename_str, "a");
- t!(s: "\\a", filename_str, "a");
- t!(s: ".", filename_str, None, opt);
- t!(s: "\\", filename_str, None, opt);
- t!(s: "..", filename_str, None, opt);
- t!(s: "..\\..", filename_str, None, opt);
- t!(s: "c:\\foo.txt", filename_str, "foo.txt");
- t!(s: "C:\\", filename_str, None, opt);
- t!(s: "C:", filename_str, None, opt);
- t!(s: "\\\\server\\share\\foo.txt", filename_str, "foo.txt");
- t!(s: "\\\\server\\share", filename_str, None, opt);
- t!(s: "\\\\server", filename_str, "server");
- t!(s: "\\\\?\\bar\\foo.txt", filename_str, "foo.txt");
- t!(s: "\\\\?\\bar", filename_str, None, opt);
- t!(s: "\\\\?\\", filename_str, None, opt);
- t!(s: "\\\\?\\UNC\\server\\share\\foo.txt", filename_str, "foo.txt");
- t!(s: "\\\\?\\UNC\\server", filename_str, None, opt);
- t!(s: "\\\\?\\UNC\\", filename_str, None, opt);
- t!(s: "\\\\?\\C:\\foo.txt", filename_str, "foo.txt");
- t!(s: "\\\\?\\C:\\", filename_str, None, opt);
- t!(s: "\\\\?\\C:", filename_str, None, opt);
- t!(s: "\\\\?\\foo/bar", filename_str, None, opt);
- t!(s: "\\\\?\\C:/foo", filename_str, None, opt);
- t!(s: "\\\\.\\foo\\bar", filename_str, "bar");
- t!(s: "\\\\.\\foo", filename_str, None, opt);
- t!(s: "\\\\.\\foo/bar", filename_str, None, opt);
- t!(s: "\\\\.\\foo\\bar/baz", filename_str, "bar/baz");
- t!(s: "\\\\.\\", filename_str, None, opt);
- t!(s: "\\\\?\\a\\b\\", filename_str, "b");
-
- t!(v: b!("a\\b\\c"), dirname, b!("a\\b"));
- t!(s: "a\\b\\c", dirname_str, "a\\b");
- t!(s: "\\a\\b\\c", dirname_str, "\\a\\b");
- t!(s: "a", dirname_str, ".");
- t!(s: "\\a", dirname_str, "\\");
- t!(s: ".", dirname_str, ".");
- t!(s: "\\", dirname_str, "\\");
- t!(s: "..", dirname_str, "..");
- t!(s: "..\\..", dirname_str, "..\\..");
- t!(s: "c:\\foo.txt", dirname_str, "C:\\");
- t!(s: "C:\\", dirname_str, "C:\\");
- t!(s: "C:", dirname_str, "C:");
- t!(s: "C:foo.txt", dirname_str, "C:");
- t!(s: "\\\\server\\share\\foo.txt", dirname_str, "\\\\server\\share");
- t!(s: "\\\\server\\share", dirname_str, "\\\\server\\share");
- t!(s: "\\\\server", dirname_str, "\\");
- t!(s: "\\\\?\\bar\\foo.txt", dirname_str, "\\\\?\\bar");
- t!(s: "\\\\?\\bar", dirname_str, "\\\\?\\bar");
- t!(s: "\\\\?\\", dirname_str, "\\\\?\\");
- t!(s: "\\\\?\\UNC\\server\\share\\foo.txt", dirname_str, "\\\\?\\UNC\\server\\share");
- t!(s: "\\\\?\\UNC\\server", dirname_str, "\\\\?\\UNC\\server\\");
- t!(s: "\\\\?\\UNC\\", dirname_str, "\\\\?\\UNC\\\\");
- t!(s: "\\\\?\\C:\\foo.txt", dirname_str, "\\\\?\\C:\\");
- t!(s: "\\\\?\\C:\\", dirname_str, "\\\\?\\C:\\");
- t!(s: "\\\\?\\C:", dirname_str, "\\\\?\\C:");
- t!(s: "\\\\?\\C:/foo/bar", dirname_str, "\\\\?\\C:/foo/bar");
- t!(s: "\\\\?\\foo/bar", dirname_str, "\\\\?\\foo/bar");
- t!(s: "\\\\.\\foo\\bar", dirname_str, "\\\\.\\foo");
- t!(s: "\\\\.\\foo", dirname_str, "\\\\.\\foo");
- t!(s: "\\\\?\\a\\b\\", dirname_str, "\\\\?\\a");
-
- t!(v: b!("hi\\there.txt"), filestem, Some(b!("there")));
- t!(s: "hi\\there.txt", filestem_str, "there");
- t!(s: "hi\\there", filestem_str, "there");
- t!(s: "there.txt", filestem_str, "there");
- t!(s: "there", filestem_str, "there");
- t!(s: ".", filestem_str, None, opt);
- t!(s: "\\", filestem_str, None, opt);
- t!(s: "foo\\.bar", filestem_str, ".bar");
- t!(s: ".bar", filestem_str, ".bar");
- t!(s: "..bar", filestem_str, ".");
- t!(s: "hi\\there..txt", filestem_str, "there.");
- t!(s: "..", filestem_str, None, opt);
- t!(s: "..\\..", filestem_str, None, opt);
- // filestem is based on filename, so we don't need the full set of prefix tests
-
- t!(v: b!("hi\\there.txt"), extension, Some(b!("txt")));
- t!(v: b!("hi\\there"), extension, None);
- t!(s: "hi\\there.txt", extension_str, Some("txt"), opt);
- t!(s: "hi\\there", extension_str, None, opt);
- t!(s: "there.txt", extension_str, Some("txt"), opt);
- t!(s: "there", extension_str, None, opt);
- t!(s: ".", extension_str, None, opt);
- t!(s: "\\", extension_str, None, opt);
- t!(s: "foo\\.bar", extension_str, None, opt);
- t!(s: ".bar", extension_str, None, opt);
- t!(s: "..bar", extension_str, Some("bar"), opt);
- t!(s: "hi\\there..txt", extension_str, Some("txt"), opt);
- t!(s: "..", extension_str, None, opt);
- t!(s: "..\\..", extension_str, None, opt);
- // extension is based on filename, so we don't need the full set of prefix tests
- }
-
- #[test]
- fn test_push() {
- macro_rules! t(
- (s: $path:expr, $join:expr) => (
- {
- let path = ($path);
- let join = ($join);
- let mut p1 = Path::new(path);
- let p2 = p1.clone();
- p1.push(join);
- assert_eq!(p1, p2.join(join));
- }
- )
- )
-
- t!(s: "a\\b\\c", "..");
- t!(s: "\\a\\b\\c", "d");
- t!(s: "a\\b", "c\\d");
- t!(s: "a\\b", "\\c\\d");
- // this is just a sanity-check test. push and join share an implementation,
- // so there's no need for the full set of prefix tests
-
- // we do want to check one odd case though to ensure the prefix is re-parsed
- let mut p = Path::new("\\\\?\\C:");
- assert_eq!(prefix(&p), Some(VerbatimPrefix(2)));
- p.push("foo");
- assert_eq!(prefix(&p), Some(VerbatimDiskPrefix));
- assert_eq!(p.as_str(), Some("\\\\?\\C:\\foo"));
-
- // and another with verbatim non-normalized paths
- let mut p = Path::new("\\\\?\\C:\\a\\");
- p.push("foo");
- assert_eq!(p.as_str(), Some("\\\\?\\C:\\a\\foo"));
- }
-
- #[test]
- fn test_push_path() {
- macro_rules! t(
- (s: $path:expr, $push:expr, $exp:expr) => (
- {
- let mut p = Path::new($path);
- let push = Path::new($push);
- p.push(&push);
- assert_eq!(p.as_str(), Some($exp));
- }
- )
- )
-
- t!(s: "a\\b\\c", "d", "a\\b\\c\\d");
- t!(s: "\\a\\b\\c", "d", "\\a\\b\\c\\d");
- t!(s: "a\\b", "c\\d", "a\\b\\c\\d");
- t!(s: "a\\b", "\\c\\d", "\\c\\d");
- t!(s: "a\\b", ".", "a\\b");
- t!(s: "a\\b", "..\\c", "a\\c");
- t!(s: "a\\b", "C:a.txt", "C:a.txt");
- t!(s: "a\\b", "..\\..\\..\\c", "..\\c");
- t!(s: "a\\b", "C:\\a.txt", "C:\\a.txt");
- t!(s: "C:\\a", "C:\\b.txt", "C:\\b.txt");
- t!(s: "C:\\a\\b\\c", "C:d", "C:\\a\\b\\c\\d");
- t!(s: "C:a\\b\\c", "C:d", "C:a\\b\\c\\d");
- t!(s: "C:a\\b", "..\\..\\..\\c", "C:..\\c");
- t!(s: "C:\\a\\b", "..\\..\\..\\c", "C:\\c");
- t!(s: "\\\\server\\share\\foo", "bar", "\\\\server\\share\\foo\\bar");
- t!(s: "\\\\server\\share\\foo", "..\\..\\bar", "\\\\server\\share\\bar");
- t!(s: "\\\\server\\share\\foo", "C:baz", "C:baz");
- t!(s: "\\\\?\\C:\\a\\b", "C:c\\d", "\\\\?\\C:\\a\\b\\c\\d");
- t!(s: "\\\\?\\C:a\\b", "C:c\\d", "C:c\\d");
- t!(s: "\\\\?\\C:\\a\\b", "C:\\c\\d", "C:\\c\\d");
- t!(s: "\\\\?\\foo\\bar", "baz", "\\\\?\\foo\\bar\\baz");
- t!(s: "\\\\?\\C:\\a\\b", "..\\..\\..\\c", "\\\\?\\C:\\a\\b\\..\\..\\..\\c");
- t!(s: "\\\\?\\foo\\bar", "..\\..\\c", "\\\\?\\foo\\bar\\..\\..\\c");
- t!(s: "\\\\?\\", "foo", "\\\\?\\\\foo");
- t!(s: "\\\\?\\UNC\\server\\share\\foo", "bar", "\\\\?\\UNC\\server\\share\\foo\\bar");
- t!(s: "\\\\?\\UNC\\server\\share", "C:\\a", "C:\\a");
- t!(s: "\\\\?\\UNC\\server\\share", "C:a", "C:a");
- t!(s: "\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\\\foo");
- t!(s: "C:\\a", "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share");
- t!(s: "\\\\.\\foo\\bar", "baz", "\\\\.\\foo\\bar\\baz");
- t!(s: "\\\\.\\foo\\bar", "C:a", "C:a");
- // again, not sure about the following, but I'm assuming \\.\ should be verbatim
- t!(s: "\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar");
-
- t!(s: "\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
- }
-
- #[test]
- fn test_push_many() {
- use to_man = at_vec::to_managed_move;
-
- macro_rules! t(
- (s: $path:expr, $push:expr, $exp:expr) => (
- {
- let mut p = Path::new($path);
- p.push_many($push);
- assert_eq!(p.as_str(), Some($exp));
- }
- );
- (v: $path:expr, $push:expr, $exp:expr) => (
- {
- let mut p = Path::new($path);
- p.push_many($push);
- assert_eq!(p.as_vec(), $exp);
- }
- )
- )
-
- t!(s: "a\\b\\c", ["d", "e"], "a\\b\\c\\d\\e");
- t!(s: "a\\b\\c", ["d", "\\e"], "\\e");
- t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
- t!(s: "a\\b\\c", [~"d", ~"e"], "a\\b\\c\\d\\e");
- t!(s: "a\\b\\c", [@"d", @"e"], "a\\b\\c\\d\\e");
- t!(v: b!("a\\b\\c"), [b!("d"), b!("e")], b!("a\\b\\c\\d\\e"));
- t!(v: b!("a\\b\\c"), [b!("d"), b!("\\e"), b!("f")], b!("\\e\\f"));
- t!(v: b!("a\\b\\c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a\\b\\c\\d\\e"));
- t!(v: b!("a\\b\\c"), [to_man(b!("d").to_owned()), to_man(b!("e").to_owned())],
- b!("a\\b\\c\\d\\e"));
- }
-
- #[test]
- fn test_pop() {
- macro_rules! t(
- (s: $path:expr, $left:expr, $right:expr) => (
- {
- let pstr = $path;
- let mut p = Path::new(pstr);
- let result = p.pop();
- let left = $left;
- assert!(p.as_str() == Some(left),
- "`{}`.pop() failed; expected remainder `{}`, found `{}`",
- pstr, left, p.as_str().unwrap());
- assert_eq!(result, $right);
- }
- );
- (v: [$($path:expr),+], [$($left:expr),+], $right:expr) => (
- {
- let mut p = Path::new(b!($($path),+));
- let result = p.pop();
- assert_eq!(p.as_vec(), b!($($left),+));
- assert_eq!(result, $right);
- }
- )
- )
-
- t!(s: "a\\b\\c", "a\\b", true);
- t!(s: "a", ".", true);
- t!(s: ".", ".", false);
- t!(s: "\\a", "\\", true);
- t!(s: "\\", "\\", false);
- t!(v: ["a\\b\\c"], ["a\\b"], true);
- t!(v: ["a"], ["."], true);
- t!(v: ["."], ["."], false);
- t!(v: ["\\a"], ["\\"], true);
- t!(v: ["\\"], ["\\"], false);
-
- t!(s: "C:\\a\\b", "C:\\a", true);
- t!(s: "C:\\a", "C:\\", true);
- t!(s: "C:\\", "C:\\", false);
- t!(s: "C:a\\b", "C:a", true);
- t!(s: "C:a", "C:", true);
- t!(s: "C:", "C:", false);
- t!(s: "\\\\server\\share\\a\\b", "\\\\server\\share\\a", true);
- t!(s: "\\\\server\\share\\a", "\\\\server\\share", true);
- t!(s: "\\\\server\\share", "\\\\server\\share", false);
- t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\b", true);
- t!(s: "\\\\?\\a\\b", "\\\\?\\a", true);
- t!(s: "\\\\?\\a", "\\\\?\\a", false);
- t!(s: "\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true);
- t!(s: "\\\\?\\C:\\a", "\\\\?\\C:\\", true);
- t!(s: "\\\\?\\C:\\", "\\\\?\\C:\\", false);
- t!(s: "\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true);
- t!(s: "\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share", true);
- t!(s: "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false);
- t!(s: "\\\\.\\a\\b\\c", "\\\\.\\a\\b", true);
- t!(s: "\\\\.\\a\\b", "\\\\.\\a", true);
- t!(s: "\\\\.\\a", "\\\\.\\a", false);
-
- t!(s: "\\\\?\\a\\b\\", "\\\\?\\a", true);
- }
-
- #[test]
- fn test_root_path() {
- assert_eq!(Path::new("a\\b\\c").root_path(), None);
- assert_eq!(Path::new("\\a\\b\\c").root_path(), Some(Path::new("\\")));
- assert_eq!(Path::new("C:a").root_path(), None);
- assert_eq!(Path::new("C:\\a").root_path(), Some(Path::new("C:\\")));
- assert_eq!(Path::new("\\\\a\\b\\c").root_path(), Some(Path::new("\\\\a\\b")));
- assert_eq!(Path::new("\\\\?\\a\\b").root_path(), Some(Path::new("\\\\?\\a")));
- assert_eq!(Path::new("\\\\?\\C:\\a").root_path(), Some(Path::new("\\\\?\\C:\\")));
- assert_eq!(Path::new("\\\\?\\UNC\\a\\b\\c").root_path(),
- Some(Path::new("\\\\?\\UNC\\a\\b")));
- assert_eq!(Path::new("\\\\.\\a\\b").root_path(), Some(Path::new("\\\\.\\a")));
- }
-
- #[test]
- fn test_join() {
- t!(s: Path::new("a\\b\\c").join(".."), "a\\b");
- t!(s: Path::new("\\a\\b\\c").join("d"), "\\a\\b\\c\\d");
- t!(s: Path::new("a\\b").join("c\\d"), "a\\b\\c\\d");
- t!(s: Path::new("a\\b").join("\\c\\d"), "\\c\\d");
- t!(s: Path::new(".").join("a\\b"), "a\\b");
- t!(s: Path::new("\\").join("a\\b"), "\\a\\b");
- t!(v: Path::new(b!("a\\b\\c")).join(b!("..")), b!("a\\b"));
- t!(v: Path::new(b!("\\a\\b\\c")).join(b!("d")), b!("\\a\\b\\c\\d"));
- // full join testing is covered under test_push_path, so no need for
- // the full set of prefix tests
- }
-
- #[test]
- fn test_join_path() {
- macro_rules! t(
- (s: $path:expr, $join:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let join = Path::new($join);
- let res = path.join(&join);
- assert_eq!(res.as_str(), Some($exp));
- }
- )
- )
-
- t!(s: "a\\b\\c", "..", "a\\b");
- t!(s: "\\a\\b\\c", "d", "\\a\\b\\c\\d");
- t!(s: "a\\b", "c\\d", "a\\b\\c\\d");
- t!(s: "a\\b", "\\c\\d", "\\c\\d");
- t!(s: ".", "a\\b", "a\\b");
- t!(s: "\\", "a\\b", "\\a\\b");
- // join is implemented using push, so there's no need for
- // the full set of prefix tests
- }
-
- #[test]
- fn test_join_many() {
- use to_man = at_vec::to_managed_move;
-
- macro_rules! t(
- (s: $path:expr, $join:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let res = path.join_many($join);
- assert_eq!(res.as_str(), Some($exp));
- }
- );
- (v: $path:expr, $join:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let res = path.join_many($join);
- assert_eq!(res.as_vec(), $exp);
- }
- )
- )
-
- t!(s: "a\\b\\c", ["d", "e"], "a\\b\\c\\d\\e");
- t!(s: "a\\b\\c", ["..", "d"], "a\\b\\d");
- t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
- t!(s: "a\\b\\c", [~"d", ~"e"], "a\\b\\c\\d\\e");
- t!(s: "a\\b\\c", [@"d", @"e"], "a\\b\\c\\d\\e");
- t!(v: b!("a\\b\\c"), [b!("d"), b!("e")], b!("a\\b\\c\\d\\e"));
- t!(v: b!("a\\b\\c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a\\b\\c\\d\\e"));
- t!(v: b!("a\\b\\c"), [to_man(b!("d").to_owned()), to_man(b!("e").to_owned())],
- b!("a\\b\\c\\d\\e"));
- }
-
- #[test]
- fn test_with_helpers() {
- macro_rules! t(
- (s: $path:expr, $op:ident, $arg:expr, $res:expr) => (
- {
- let pstr = $path;
- let path = Path::new(pstr);
- let arg = $arg;
- let res = path.$op(arg);
- let exp = $res;
- assert!(res.as_str() == Some(exp),
- "`{}`.{}(\"{}\"): Expected `{}`, found `{}`",
- pstr, stringify!($op), arg, exp, res.as_str().unwrap());
- }
- )
- )
-
- t!(s: "a\\b\\c", with_filename, "d", "a\\b\\d");
- t!(s: ".", with_filename, "foo", "foo");
- t!(s: "\\a\\b\\c", with_filename, "d", "\\a\\b\\d");
- t!(s: "\\", with_filename, "foo", "\\foo");
- t!(s: "\\a", with_filename, "foo", "\\foo");
- t!(s: "foo", with_filename, "bar", "bar");
- t!(s: "\\", with_filename, "foo\\", "\\foo");
- t!(s: "\\a", with_filename, "foo\\", "\\foo");
- t!(s: "a\\b\\c", with_filename, "", "a\\b");
- t!(s: "a\\b\\c", with_filename, ".", "a\\b");
- t!(s: "a\\b\\c", with_filename, "..", "a");
- t!(s: "\\a", with_filename, "", "\\");
- t!(s: "foo", with_filename, "", ".");
- t!(s: "a\\b\\c", with_filename, "d\\e", "a\\b\\d\\e");
- t!(s: "a\\b\\c", with_filename, "\\d", "a\\b\\d");
- t!(s: "..", with_filename, "foo", "..\\foo");
- t!(s: "..\\..", with_filename, "foo", "..\\..\\foo");
- t!(s: "..", with_filename, "", "..");
- t!(s: "..\\..", with_filename, "", "..\\..");
- t!(s: "C:\\foo\\bar", with_filename, "baz", "C:\\foo\\baz");
- t!(s: "C:\\foo", with_filename, "bar", "C:\\bar");
- t!(s: "C:\\", with_filename, "foo", "C:\\foo");
- t!(s: "C:foo\\bar", with_filename, "baz", "C:foo\\baz");
- t!(s: "C:foo", with_filename, "bar", "C:bar");
- t!(s: "C:", with_filename, "foo", "C:foo");
- t!(s: "C:\\foo", with_filename, "", "C:\\");
- t!(s: "C:foo", with_filename, "", "C:");
- t!(s: "C:\\foo\\bar", with_filename, "..", "C:\\");
- t!(s: "C:\\foo", with_filename, "..", "C:\\");
- t!(s: "C:\\", with_filename, "..", "C:\\");
- t!(s: "C:foo\\bar", with_filename, "..", "C:");
- t!(s: "C:foo", with_filename, "..", "C:..");
- t!(s: "C:", with_filename, "..", "C:..");
- t!(s: "\\\\server\\share\\foo", with_filename, "bar", "\\\\server\\share\\bar");
- t!(s: "\\\\server\\share", with_filename, "foo", "\\\\server\\share\\foo");
- t!(s: "\\\\server\\share\\foo", with_filename, "", "\\\\server\\share");
- t!(s: "\\\\server\\share", with_filename, "", "\\\\server\\share");
- t!(s: "\\\\server\\share\\foo", with_filename, "..", "\\\\server\\share");
- t!(s: "\\\\server\\share", with_filename, "..", "\\\\server\\share");
- t!(s: "\\\\?\\C:\\foo\\bar", with_filename, "baz", "\\\\?\\C:\\foo\\baz");
- t!(s: "\\\\?\\C:\\foo", with_filename, "bar", "\\\\?\\C:\\bar");
- t!(s: "\\\\?\\C:\\", with_filename, "foo", "\\\\?\\C:\\foo");
- t!(s: "\\\\?\\C:\\foo", with_filename, "..", "\\\\?\\C:\\..");
- t!(s: "\\\\?\\foo\\bar", with_filename, "baz", "\\\\?\\foo\\baz");
- t!(s: "\\\\?\\foo", with_filename, "bar", "\\\\?\\foo\\bar");
- t!(s: "\\\\?\\", with_filename, "foo", "\\\\?\\\\foo");
- t!(s: "\\\\?\\foo\\bar", with_filename, "..", "\\\\?\\foo\\..");
- t!(s: "\\\\.\\foo\\bar", with_filename, "baz", "\\\\.\\foo\\baz");
- t!(s: "\\\\.\\foo", with_filename, "bar", "\\\\.\\foo\\bar");
- t!(s: "\\\\.\\foo\\bar", with_filename, "..", "\\\\.\\foo\\..");
-
- t!(s: "hi\\there.txt", with_extension, "exe", "hi\\there.exe");
- t!(s: "hi\\there.txt", with_extension, "", "hi\\there");
- t!(s: "hi\\there.txt", with_extension, ".", "hi\\there..");
- t!(s: "hi\\there.txt", with_extension, "..", "hi\\there...");
- t!(s: "hi\\there", with_extension, "txt", "hi\\there.txt");
- t!(s: "hi\\there", with_extension, ".", "hi\\there..");
- t!(s: "hi\\there", with_extension, "..", "hi\\there...");
- t!(s: "hi\\there.", with_extension, "txt", "hi\\there.txt");
- t!(s: "hi\\.foo", with_extension, "txt", "hi\\.foo.txt");
- t!(s: "hi\\there.txt", with_extension, ".foo", "hi\\there..foo");
- t!(s: "\\", with_extension, "txt", "\\");
- t!(s: "\\", with_extension, ".", "\\");
- t!(s: "\\", with_extension, "..", "\\");
- t!(s: ".", with_extension, "txt", ".");
- // extension setter calls filename setter internally, no need for extended tests
- }
-
- #[test]
- fn test_setters() {
- macro_rules! t(
- (s: $path:expr, $set:ident, $with:ident, $arg:expr) => (
- {
- let path = $path;
- let arg = $arg;
- let mut p1 = Path::new(path);
- p1.$set(arg);
- let p2 = Path::new(path);
- assert_eq!(p1, p2.$with(arg));
- }
- );
- (v: $path:expr, $set:ident, $with:ident, $arg:expr) => (
- {
- let path = $path;
- let arg = $arg;
- let mut p1 = Path::new(path);
- p1.$set(arg);
- let p2 = Path::new(path);
- assert_eq!(p1, p2.$with(arg));
- }
- )
- )
-
- t!(v: b!("a\\b\\c"), set_filename, with_filename, b!("d"));
- t!(v: b!("\\"), set_filename, with_filename, b!("foo"));
- t!(s: "a\\b\\c", set_filename, with_filename, "d");
- t!(s: "\\", set_filename, with_filename, "foo");
- t!(s: ".", set_filename, with_filename, "foo");
- t!(s: "a\\b", set_filename, with_filename, "");
- t!(s: "a", set_filename, with_filename, "");
-
- t!(v: b!("hi\\there.txt"), set_extension, with_extension, b!("exe"));
- t!(s: "hi\\there.txt", set_extension, with_extension, "exe");
- t!(s: "hi\\there.", set_extension, with_extension, "txt");
- t!(s: "hi\\there", set_extension, with_extension, "txt");
- t!(s: "hi\\there.txt", set_extension, with_extension, "");
- t!(s: "hi\\there", set_extension, with_extension, "");
- t!(s: ".", set_extension, with_extension, "txt");
-
- // with_ helpers use the setter internally, so the tests for the with_ helpers
- // will suffice. No need for the full set of prefix tests.
- }
-
- #[test]
- fn test_getters() {
- macro_rules! t(
- (s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
- {
- let path = $path;
- let filename = $filename;
- assert!(path.filename_str() == filename,
- "`{}`.filename_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), filename, path.filename_str());
- let dirname = $dirname;
- assert!(path.dirname_str() == dirname,
- "`{}`.dirname_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), dirname, path.dirname_str());
- let filestem = $filestem;
- assert!(path.filestem_str() == filestem,
- "`{}`.filestem_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), filestem, path.filestem_str());
- let ext = $ext;
- assert!(path.extension_str() == ext,
- "`{}`.extension_str(): Expected `{:?}`, found `{:?}`",
- path.as_str().unwrap(), ext, path.extension_str());
- }
- );
- (v: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
- {
- let path = $path;
- assert_eq!(path.filename(), $filename);
- assert_eq!(path.dirname(), $dirname);
- assert_eq!(path.filestem(), $filestem);
- assert_eq!(path.extension(), $ext);
- }
- )
- )
-
- t!(v: Path::new(b!("a\\b\\c")), Some(b!("c")), b!("a\\b"), Some(b!("c")), None);
- t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
- t!(s: Path::new("."), None, Some("."), None, None);
- t!(s: Path::new("\\"), None, Some("\\"), None, None);
- t!(s: Path::new(".."), None, Some(".."), None, None);
- t!(s: Path::new("..\\.."), None, Some("..\\.."), None, None);
- t!(s: Path::new("hi\\there.txt"), Some("there.txt"), Some("hi"),
- Some("there"), Some("txt"));
- t!(s: Path::new("hi\\there"), Some("there"), Some("hi"), Some("there"), None);
- t!(s: Path::new("hi\\there."), Some("there."), Some("hi"),
- Some("there"), Some(""));
- t!(s: Path::new("hi\\.there"), Some(".there"), Some("hi"), Some(".there"), None);
- t!(s: Path::new("hi\\..there"), Some("..there"), Some("hi"),
- Some("."), Some("there"));
-
- // these are already tested in test_components, so no need for extended tests
- }
-
- #[test]
- fn test_dir_path() {
- t!(s: Path::new("hi\\there").dir_path(), "hi");
- t!(s: Path::new("hi").dir_path(), ".");
- t!(s: Path::new("\\hi").dir_path(), "\\");
- t!(s: Path::new("\\").dir_path(), "\\");
- t!(s: Path::new("..").dir_path(), "..");
- t!(s: Path::new("..\\..").dir_path(), "..\\..");
-
- // dir_path is just dirname interpreted as a path.
- // No need for extended tests
- }
-
- #[test]
- fn test_is_absolute() {
- macro_rules! t(
- ($path:expr, $abs:expr, $vol:expr, $cwd:expr, $rel:expr) => (
- {
- let path = Path::new($path);
- let (abs, vol, cwd, rel) = ($abs, $vol, $cwd, $rel);
- let b = path.is_absolute();
- assert!(b == abs, "Path '{}'.is_absolute(): expected {:?}, found {:?}",
- path.as_str().unwrap(), abs, b);
- let b = is_vol_relative(&path);
- assert!(b == vol, "is_vol_relative('{}'): expected {:?}, found {:?}",
- path.as_str().unwrap(), vol, b);
- let b = is_cwd_relative(&path);
- assert!(b == cwd, "is_cwd_relative('{}'): expected {:?}, found {:?}",
- path.as_str().unwrap(), cwd, b);
- let b = path.is_relative();
- assert!(b == rel, "Path '{}'.is_relativf(): expected {:?}, found {:?}",
- path.as_str().unwrap(), rel, b);
- }
- )
- )
- t!("a\\b\\c", false, false, false, true);
- t!("\\a\\b\\c", false, true, false, false);
- t!("a", false, false, false, true);
- t!("\\a", false, true, false, false);
- t!(".", false, false, false, true);
- t!("\\", false, true, false, false);
- t!("..", false, false, false, true);
- t!("..\\..", false, false, false, true);
- t!("C:a\\b.txt", false, false, true, false);
- t!("C:\\a\\b.txt", true, false, false, false);
- t!("\\\\server\\share\\a\\b.txt", true, false, false, false);
- t!("\\\\?\\a\\b\\c.txt", true, false, false, false);
- t!("\\\\?\\C:\\a\\b.txt", true, false, false, false);
- t!("\\\\?\\C:a\\b.txt", true, false, false, false); // NB: not equivalent to C:a\b.txt
- t!("\\\\?\\UNC\\server\\share\\a\\b.txt", true, false, false, false);
- t!("\\\\.\\a\\b", true, false, false, false);
- }
-
- #[test]
- fn test_is_ancestor_of() {
- macro_rules! t(
- (s: $path:expr, $dest:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let dest = Path::new($dest);
- let exp = $exp;
- let res = path.is_ancestor_of(&dest);
- assert!(res == exp,
- "`{}`.is_ancestor_of(`{}`): Expected {:?}, found {:?}",
- path.as_str().unwrap(), dest.as_str().unwrap(), exp, res);
- }
- )
- )
-
- t!(s: "a\\b\\c", "a\\b\\c\\d", true);
- t!(s: "a\\b\\c", "a\\b\\c", true);
- t!(s: "a\\b\\c", "a\\b", false);
- t!(s: "\\a\\b\\c", "\\a\\b\\c", true);
- t!(s: "\\a\\b", "\\a\\b\\c", true);
- t!(s: "\\a\\b\\c\\d", "\\a\\b\\c", false);
- t!(s: "\\a\\b", "a\\b\\c", false);
- t!(s: "a\\b", "\\a\\b\\c", false);
- t!(s: "a\\b\\c", "a\\b\\d", false);
- t!(s: "..\\a\\b\\c", "a\\b\\c", false);
- t!(s: "a\\b\\c", "..\\a\\b\\c", false);
- t!(s: "a\\b\\c", "a\\b\\cd", false);
- t!(s: "a\\b\\cd", "a\\b\\c", false);
- t!(s: "..\\a\\b", "..\\a\\b\\c", true);
- t!(s: ".", "a\\b", true);
- t!(s: ".", ".", true);
- t!(s: "\\", "\\", true);
- t!(s: "\\", "\\a\\b", true);
- t!(s: "..", "a\\b", true);
- t!(s: "..\\..", "a\\b", true);
- t!(s: "foo\\bar", "foobar", false);
- t!(s: "foobar", "foo\\bar", false);
-
- t!(s: "foo", "C:foo", false);
- t!(s: "C:foo", "foo", false);
- t!(s: "C:foo", "C:foo\\bar", true);
- t!(s: "C:foo\\bar", "C:foo", false);
- t!(s: "C:\\foo", "C:\\foo\\bar", true);
- t!(s: "C:", "C:", true);
- t!(s: "C:", "C:\\", false);
- t!(s: "C:\\", "C:", false);
- t!(s: "C:\\", "C:\\", true);
- t!(s: "C:\\foo\\bar", "C:\\foo", false);
- t!(s: "C:foo\\bar", "C:foo", false);
- t!(s: "C:\\foo", "\\foo", false);
- t!(s: "\\foo", "C:\\foo", false);
- t!(s: "\\\\server\\share\\foo", "\\\\server\\share\\foo\\bar", true);
- t!(s: "\\\\server\\share", "\\\\server\\share\\foo", true);
- t!(s: "\\\\server\\share\\foo", "\\\\server\\share", false);
- t!(s: "C:\\foo", "\\\\server\\share\\foo", false);
- t!(s: "\\\\server\\share\\foo", "C:\\foo", false);
- t!(s: "\\\\?\\foo\\bar", "\\\\?\\foo\\bar\\baz", true);
- t!(s: "\\\\?\\foo\\bar\\baz", "\\\\?\\foo\\bar", false);
- t!(s: "\\\\?\\foo\\bar", "\\foo\\bar\\baz", false);
- t!(s: "\\foo\\bar", "\\\\?\\foo\\bar\\baz", false);
- t!(s: "\\\\?\\C:\\foo\\bar", "\\\\?\\C:\\foo\\bar\\baz", true);
- t!(s: "\\\\?\\C:\\foo\\bar\\baz", "\\\\?\\C:\\foo\\bar", false);
- t!(s: "\\\\?\\C:\\", "\\\\?\\C:\\foo", true);
- t!(s: "\\\\?\\C:", "\\\\?\\C:\\", false); // this is a weird one
- t!(s: "\\\\?\\C:\\", "\\\\?\\C:", false);
- t!(s: "\\\\?\\C:\\a", "\\\\?\\c:\\a\\b", true);
- t!(s: "\\\\?\\c:\\a", "\\\\?\\C:\\a\\b", true);
- t!(s: "\\\\?\\C:\\a", "\\\\?\\D:\\a\\b", false);
- t!(s: "\\\\?\\foo", "\\\\?\\foobar", false);
- t!(s: "\\\\?\\a\\b", "\\\\?\\a\\b\\c", true);
- t!(s: "\\\\?\\a\\b", "\\\\?\\a\\b\\", true);
- t!(s: "\\\\?\\a\\b\\", "\\\\?\\a\\b", true);
- t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\b", false);
- t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\b\\", false);
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\?\\UNC\\a\\b\\c\\d", true);
- t!(s: "\\\\?\\UNC\\a\\b\\c\\d", "\\\\?\\UNC\\a\\b\\c", false);
- t!(s: "\\\\?\\UNC\\a\\b", "\\\\?\\UNC\\a\\b\\c", true);
- t!(s: "\\\\.\\foo\\bar", "\\\\.\\foo\\bar\\baz", true);
- t!(s: "\\\\.\\foo\\bar\\baz", "\\\\.\\foo\\bar", false);
- t!(s: "\\\\.\\foo", "\\\\.\\foo\\bar", true);
- t!(s: "\\\\.\\foo", "\\\\.\\foobar", false);
-
- t!(s: "\\a\\b", "\\\\?\\a\\b", false);
- t!(s: "\\\\?\\a\\b", "\\a\\b", false);
- t!(s: "\\a\\b", "\\\\?\\C:\\a\\b", false);
- t!(s: "\\\\?\\C:\\a\\b", "\\a\\b", false);
- t!(s: "Z:\\a\\b", "\\\\?\\z:\\a\\b", true);
- t!(s: "C:\\a\\b", "\\\\?\\D:\\a\\b", false);
- t!(s: "a\\b", "\\\\?\\a\\b", false);
- t!(s: "\\\\?\\a\\b", "a\\b", false);
- t!(s: "C:\\a\\b", "\\\\?\\C:\\a\\b", true);
- t!(s: "\\\\?\\C:\\a\\b", "C:\\a\\b", true);
- t!(s: "C:a\\b", "\\\\?\\C:\\a\\b", false);
- t!(s: "C:a\\b", "\\\\?\\C:a\\b", false);
- t!(s: "\\\\?\\C:\\a\\b", "C:a\\b", false);
- t!(s: "\\\\?\\C:a\\b", "C:a\\b", false);
- t!(s: "C:\\a\\b", "\\\\?\\C:\\a\\b\\", true);
- t!(s: "\\\\?\\C:\\a\\b\\", "C:\\a\\b", true);
- t!(s: "\\\\a\\b\\c", "\\\\?\\UNC\\a\\b\\c", true);
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\a\\b\\c", true);
- }
-
- #[test]
- fn test_ends_with_path() {
- macro_rules! t(
- (s: $path:expr, $child:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let child = Path::new($child);
- assert_eq!(path.ends_with_path(&child), $exp);
- }
- );
- )
-
- t!(s: "a\\b\\c", "c", true);
- t!(s: "a\\b\\c", "d", false);
- t!(s: "foo\\bar\\quux", "bar", false);
- t!(s: "foo\\bar\\quux", "barquux", false);
- t!(s: "a\\b\\c", "b\\c", true);
- t!(s: "a\\b\\c", "a\\b\\c", true);
- t!(s: "a\\b\\c", "foo\\a\\b\\c", false);
- t!(s: "\\a\\b\\c", "a\\b\\c", true);
- t!(s: "\\a\\b\\c", "\\a\\b\\c", false); // child must be relative
- t!(s: "\\a\\b\\c", "foo\\a\\b\\c", false);
- t!(s: "a\\b\\c", "", false);
- t!(s: "", "", true);
- t!(s: "\\a\\b\\c", "d\\e\\f", false);
- t!(s: "a\\b\\c", "a\\b", false);
- t!(s: "a\\b\\c", "b", false);
- t!(s: "C:\\a\\b", "b", true);
- t!(s: "C:\\a\\b", "C:b", false);
- t!(s: "C:\\a\\b", "C:a\\b", false);
- }
-
- #[test]
- fn test_path_relative_from() {
- macro_rules! t(
- (s: $path:expr, $other:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let other = Path::new($other);
- let res = path.path_relative_from(&other);
- let exp = $exp;
- assert!(res.as_ref().and_then(|x| x.as_str()) == exp,
- "`{}`.path_relative_from(`{}`): Expected {:?}, got {:?}",
- path.as_str().unwrap(), other.as_str().unwrap(), exp,
- res.as_ref().and_then(|x| x.as_str()));
- }
- )
- )
-
- t!(s: "a\\b\\c", "a\\b", Some("c"));
- t!(s: "a\\b\\c", "a\\b\\d", Some("..\\c"));
- t!(s: "a\\b\\c", "a\\b\\c\\d", Some(".."));
- t!(s: "a\\b\\c", "a\\b\\c", Some("."));
- t!(s: "a\\b\\c", "a\\b\\c\\d\\e", Some("..\\.."));
- t!(s: "a\\b\\c", "a\\d\\e", Some("..\\..\\b\\c"));
- t!(s: "a\\b\\c", "d\\e\\f", Some("..\\..\\..\\a\\b\\c"));
- t!(s: "a\\b\\c", "\\a\\b\\c", None);
- t!(s: "\\a\\b\\c", "a\\b\\c", Some("\\a\\b\\c"));
- t!(s: "\\a\\b\\c", "\\a\\b\\c\\d", Some(".."));
- t!(s: "\\a\\b\\c", "\\a\\b", Some("c"));
- t!(s: "\\a\\b\\c", "\\a\\b\\c\\d\\e", Some("..\\.."));
- t!(s: "\\a\\b\\c", "\\a\\d\\e", Some("..\\..\\b\\c"));
- t!(s: "\\a\\b\\c", "\\d\\e\\f", Some("..\\..\\..\\a\\b\\c"));
- t!(s: "hi\\there.txt", "hi\\there", Some("..\\there.txt"));
- t!(s: ".", "a", Some(".."));
- t!(s: ".", "a\\b", Some("..\\.."));
- t!(s: ".", ".", Some("."));
- t!(s: "a", ".", Some("a"));
- t!(s: "a\\b", ".", Some("a\\b"));
- t!(s: "..", ".", Some(".."));
- t!(s: "a\\b\\c", "a\\b\\c", Some("."));
- t!(s: "\\a\\b\\c", "\\a\\b\\c", Some("."));
- t!(s: "\\", "\\", Some("."));
- t!(s: "\\", ".", Some("\\"));
- t!(s: "..\\..\\a", "b", Some("..\\..\\..\\a"));
- t!(s: "a", "..\\..\\b", None);
- t!(s: "..\\..\\a", "..\\..\\b", Some("..\\a"));
- t!(s: "..\\..\\a", "..\\..\\a\\b", Some(".."));
- t!(s: "..\\..\\a\\b", "..\\..\\a", Some("b"));
-
- t!(s: "C:a\\b\\c", "C:a\\b", Some("c"));
- t!(s: "C:a\\b", "C:a\\b\\c", Some(".."));
- t!(s: "C:" ,"C:a\\b", Some("..\\.."));
- t!(s: "C:a\\b", "C:c\\d", Some("..\\..\\a\\b"));
- t!(s: "C:a\\b", "D:c\\d", Some("C:a\\b"));
- t!(s: "C:a\\b", "C:..\\c", None);
- t!(s: "C:..\\a", "C:b\\c", Some("..\\..\\..\\a"));
- t!(s: "C:\\a\\b\\c", "C:\\a\\b", Some("c"));
- t!(s: "C:\\a\\b", "C:\\a\\b\\c", Some(".."));
- t!(s: "C:\\", "C:\\a\\b", Some("..\\.."));
- t!(s: "C:\\a\\b", "C:\\c\\d", Some("..\\..\\a\\b"));
- t!(s: "C:\\a\\b", "C:a\\b", Some("C:\\a\\b"));
- t!(s: "C:a\\b", "C:\\a\\b", None);
- t!(s: "\\a\\b", "C:\\a\\b", None);
- t!(s: "\\a\\b", "C:a\\b", None);
- t!(s: "a\\b", "C:\\a\\b", None);
- t!(s: "a\\b", "C:a\\b", None);
-
- t!(s: "\\\\a\\b\\c", "\\\\a\\b", Some("c"));
- t!(s: "\\\\a\\b", "\\\\a\\b\\c", Some(".."));
- t!(s: "\\\\a\\b\\c\\e", "\\\\a\\b\\c\\d", Some("..\\e"));
- t!(s: "\\\\a\\c\\d", "\\\\a\\b\\d", Some("\\\\a\\c\\d"));
- t!(s: "\\\\b\\c\\d", "\\\\a\\c\\d", Some("\\\\b\\c\\d"));
- t!(s: "\\\\a\\b\\c", "\\d\\e", Some("\\\\a\\b\\c"));
- t!(s: "\\d\\e", "\\\\a\\b\\c", None);
- t!(s: "d\\e", "\\\\a\\b\\c", None);
- t!(s: "C:\\a\\b\\c", "\\\\a\\b\\c", Some("C:\\a\\b\\c"));
- t!(s: "C:\\c", "\\\\a\\b\\c", Some("C:\\c"));
-
- t!(s: "\\\\?\\a\\b", "\\a\\b", Some("\\\\?\\a\\b"));
- t!(s: "\\\\?\\a\\b", "a\\b", Some("\\\\?\\a\\b"));
- t!(s: "\\\\?\\a\\b", "\\b", Some("\\\\?\\a\\b"));
- t!(s: "\\\\?\\a\\b", "b", Some("\\\\?\\a\\b"));
- t!(s: "\\\\?\\a\\b", "\\\\?\\a\\b\\c", Some(".."));
- t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\b", Some("c"));
- t!(s: "\\\\?\\a\\b", "\\\\?\\c\\d", Some("\\\\?\\a\\b"));
- t!(s: "\\\\?\\a", "\\\\?\\b", Some("\\\\?\\a"));
-
- t!(s: "\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", Some("b"));
- t!(s: "\\\\?\\C:\\a", "\\\\?\\C:\\a\\b", Some(".."));
- t!(s: "\\\\?\\C:\\a", "\\\\?\\C:\\b", Some("..\\a"));
- t!(s: "\\\\?\\C:\\a", "\\\\?\\D:\\a", Some("\\\\?\\C:\\a"));
- t!(s: "\\\\?\\C:\\a\\b", "\\\\?\\c:\\a", Some("b"));
- t!(s: "\\\\?\\C:\\a\\b", "C:\\a", Some("b"));
- t!(s: "\\\\?\\C:\\a", "C:\\a\\b", Some(".."));
- t!(s: "C:\\a\\b", "\\\\?\\C:\\a", Some("b"));
- t!(s: "C:\\a", "\\\\?\\C:\\a\\b", Some(".."));
- t!(s: "\\\\?\\C:\\a", "D:\\a", Some("\\\\?\\C:\\a"));
- t!(s: "\\\\?\\c:\\a\\b", "C:\\a", Some("b"));
- t!(s: "\\\\?\\C:\\a\\b", "C:a\\b", Some("\\\\?\\C:\\a\\b"));
- t!(s: "\\\\?\\C:\\a\\.\\b", "C:\\a", Some("\\\\?\\C:\\a\\.\\b"));
- t!(s: "\\\\?\\C:\\a\\b/c", "C:\\a", Some("\\\\?\\C:\\a\\b/c"));
- t!(s: "\\\\?\\C:\\a\\..\\b", "C:\\a", Some("\\\\?\\C:\\a\\..\\b"));
- t!(s: "C:a\\b", "\\\\?\\C:\\a\\b", None);
- t!(s: "\\\\?\\C:\\a\\.\\b", "\\\\?\\C:\\a", Some("\\\\?\\C:\\a\\.\\b"));
- t!(s: "\\\\?\\C:\\a\\b/c", "\\\\?\\C:\\a", Some("\\\\?\\C:\\a\\b/c"));
- t!(s: "\\\\?\\C:\\a\\..\\b", "\\\\?\\C:\\a", Some("\\\\?\\C:\\a\\..\\b"));
- t!(s: "\\\\?\\C:\\a\\b\\", "\\\\?\\C:\\a", Some("b"));
- t!(s: "\\\\?\\C:\\.\\b", "\\\\?\\C:\\.", Some("b"));
- t!(s: "C:\\b", "\\\\?\\C:\\.", Some("..\\b"));
- t!(s: "\\\\?\\a\\.\\b\\c", "\\\\?\\a\\.\\b", Some("c"));
- t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\.\\d", Some("..\\..\\b\\c"));
- t!(s: "\\\\?\\a\\..\\b", "\\\\?\\a\\..", Some("b"));
- t!(s: "\\\\?\\a\\b\\..", "\\\\?\\a\\b", Some("\\\\?\\a\\b\\.."));
- t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\..\\b", Some("..\\..\\b\\c"));
-
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\?\\UNC\\a\\b", Some("c"));
- t!(s: "\\\\?\\UNC\\a\\b", "\\\\?\\UNC\\a\\b\\c", Some(".."));
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\?\\UNC\\a\\c\\d", Some("\\\\?\\UNC\\a\\b\\c"));
- t!(s: "\\\\?\\UNC\\b\\c\\d", "\\\\?\\UNC\\a\\c\\d", Some("\\\\?\\UNC\\b\\c\\d"));
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\?\\a\\b\\c", Some("\\\\?\\UNC\\a\\b\\c"));
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\?\\C:\\a\\b\\c", Some("\\\\?\\UNC\\a\\b\\c"));
- t!(s: "\\\\?\\UNC\\a\\b\\c/d", "\\\\?\\UNC\\a\\b", Some("\\\\?\\UNC\\a\\b\\c/d"));
- t!(s: "\\\\?\\UNC\\a\\b\\.", "\\\\?\\UNC\\a\\b", Some("\\\\?\\UNC\\a\\b\\."));
- t!(s: "\\\\?\\UNC\\a\\b\\..", "\\\\?\\UNC\\a\\b", Some("\\\\?\\UNC\\a\\b\\.."));
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\a\\b", Some("c"));
- t!(s: "\\\\?\\UNC\\a\\b", "\\\\a\\b\\c", Some(".."));
- t!(s: "\\\\?\\UNC\\a\\b\\c", "\\\\a\\c\\d", Some("\\\\?\\UNC\\a\\b\\c"));
- t!(s: "\\\\?\\UNC\\b\\c\\d", "\\\\a\\c\\d", Some("\\\\?\\UNC\\b\\c\\d"));
- t!(s: "\\\\?\\UNC\\a\\b\\.", "\\\\a\\b", Some("\\\\?\\UNC\\a\\b\\."));
- t!(s: "\\\\?\\UNC\\a\\b\\c/d", "\\\\a\\b", Some("\\\\?\\UNC\\a\\b\\c/d"));
- t!(s: "\\\\?\\UNC\\a\\b\\..", "\\\\a\\b", Some("\\\\?\\UNC\\a\\b\\.."));
- t!(s: "\\\\a\\b\\c", "\\\\?\\UNC\\a\\b", Some("c"));
- t!(s: "\\\\a\\b\\c", "\\\\?\\UNC\\a\\c\\d", Some("\\\\a\\b\\c"));
- }
-
- #[test]
- fn test_str_components() {
- macro_rules! t(
- (s: $path:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let comps = path.str_components().map(|x|x.unwrap()).to_owned_vec();
- let exp: &[&str] = $exp;
- assert!(comps.as_slice() == exp,
- "str_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- let comps = path.rev_str_components().map(|x|x.unwrap()).to_owned_vec();
- let exp = exp.rev_iter().map(|&x|x).to_owned_vec();
- assert!(comps.as_slice() == exp,
- "rev_str_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- }
- );
- (v: [$($arg:expr),+], $exp:expr) => (
- {
- let path = Path::new(b!($($arg),+));
- let comps = path.str_components().map(|x|x.unwrap()).to_owned_vec();
- let exp: &[&str] = $exp;
- assert!(comps.as_slice() == exp,
- "str_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- let comps = path.rev_str_components().map(|x|x.unwrap()).to_owned_vec();
- let exp = exp.rev_iter().map(|&x|x).to_owned_vec();
- assert!(comps.as_slice() == exp,
- "rev_str_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- }
- )
- )
-
- t!(v: ["a\\b\\c"], ["a", "b", "c"]);
- t!(s: "a\\b\\c", ["a", "b", "c"]);
- t!(s: "a\\b\\d", ["a", "b", "d"]);
- t!(s: "a\\b\\cd", ["a", "b", "cd"]);
- t!(s: "\\a\\b\\c", ["a", "b", "c"]);
- t!(s: "a", ["a"]);
- t!(s: "\\a", ["a"]);
- t!(s: "\\", []);
- t!(s: ".", ["."]);
- t!(s: "..", [".."]);
- t!(s: "..\\..", ["..", ".."]);
- t!(s: "..\\..\\foo", ["..", "..", "foo"]);
- t!(s: "C:foo\\bar", ["foo", "bar"]);
- t!(s: "C:foo", ["foo"]);
- t!(s: "C:", []);
- t!(s: "C:\\foo\\bar", ["foo", "bar"]);
- t!(s: "C:\\foo", ["foo"]);
- t!(s: "C:\\", []);
- t!(s: "\\\\server\\share\\foo\\bar", ["foo", "bar"]);
- t!(s: "\\\\server\\share\\foo", ["foo"]);
- t!(s: "\\\\server\\share", []);
- t!(s: "\\\\?\\foo\\bar\\baz", ["bar", "baz"]);
- t!(s: "\\\\?\\foo\\bar", ["bar"]);
- t!(s: "\\\\?\\foo", []);
- t!(s: "\\\\?\\", []);
- t!(s: "\\\\?\\a\\b", ["b"]);
- t!(s: "\\\\?\\a\\b\\", ["b"]);
- t!(s: "\\\\?\\foo\\bar\\\\baz", ["bar", "", "baz"]);
- t!(s: "\\\\?\\C:\\foo\\bar", ["foo", "bar"]);
- t!(s: "\\\\?\\C:\\foo", ["foo"]);
- t!(s: "\\\\?\\C:\\", []);
- t!(s: "\\\\?\\C:\\foo\\", ["foo"]);
- t!(s: "\\\\?\\UNC\\server\\share\\foo\\bar", ["foo", "bar"]);
- t!(s: "\\\\?\\UNC\\server\\share\\foo", ["foo"]);
- t!(s: "\\\\?\\UNC\\server\\share", []);
- t!(s: "\\\\.\\foo\\bar\\baz", ["bar", "baz"]);
- t!(s: "\\\\.\\foo\\bar", ["bar"]);
- t!(s: "\\\\.\\foo", []);
- }
-
- #[test]
- fn test_components_iter() {
- macro_rules! t(
- (s: $path:expr, $exp:expr) => (
- {
- let path = Path::new($path);
- let comps = path.components().to_owned_vec();
- let exp: &[&[u8]] = $exp;
- assert!(comps.as_slice() == exp, "components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- let comps = path.rev_components().to_owned_vec();
- let exp = exp.rev_iter().map(|&x|x).to_owned_vec();
- assert!(comps.as_slice() == exp,
- "rev_components: Expected {:?}, found {:?}",
- comps.as_slice(), exp);
- }
- )
- )
-
- t!(s: "a\\b\\c", [b!("a"), b!("b"), b!("c")]);
- t!(s: ".", [b!(".")]);
- // since this is really a wrapper around str_components, those tests suffice
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Many programming languages have a 'prelude': a particular subset of the
-libraries that come with the language. Every program imports the prelude by
-default.
-
-For example, it would be annoying to add `use std::io::println;` to every single
-program, and the vast majority of Rust programs will wish to print to standard
-output. Therefore, it makes sense to import it into every program.
-
-Rust's prelude has three main parts:
-
-1. io::print and io::println.
-2. Core operators, such as `Add`, `Mul`, and `Not`.
-3. Various types and traits, such as `Clone`, `Eq`, and `comm::Chan`.
-
-*/
-
-// Reexported core operators
-pub use either::{Either, Left, Right};
-pub use kinds::Sized;
-pub use kinds::{Freeze, Send};
-pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
-pub use ops::{BitAnd, BitOr, BitXor};
-pub use ops::{Drop};
-pub use ops::{Shl, Shr, Index};
-pub use option::{Option, Some, None};
-pub use result::{Result, Ok, Err};
-
-// Reexported functions
-pub use from_str::from_str;
-pub use iter::range;
-pub use io::stdio::{print, println};
-
-// Reexported types and traits
-
-pub use any::{Any, AnyOwnExt, AnyRefExt, AnyMutRefExt};
-pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr, ToBytesConsume};
-pub use bool::Bool;
-pub use c_str::ToCStr;
-pub use char::Char;
-pub use clone::{Clone, DeepClone};
-pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
-pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
-pub use default::Default;
-pub use from_str::FromStr;
-pub use hash::Hash;
-pub use iter::{FromIterator, Extendable};
-pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, ClonableIterator};
-pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
-pub use num::Times;
-pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
-pub use num::{Bitwise, BitCount, Bounded};
-pub use num::{Integer, Fractional, Real, RealExt};
-pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
-pub use num::{Orderable, Signed, Unsigned, Round};
-pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive};
-pub use path::{GenericPath, Path, PosixPath, WindowsPath};
-pub use ptr::RawPtr;
-pub use io::{Buffer, Writer, Reader, Seek};
-pub use send_str::{SendStr, SendStrOwned, SendStrStatic, IntoSendStr};
-pub use str::{Str, StrVector, StrSlice, OwnedStr};
-pub use to_bytes::IterBytes;
-pub use to_str::{ToStr, ToStrConsume};
-pub use tuple::{CopyableTuple, ImmutableTuple};
-pub use tuple::{ImmutableTuple1, ImmutableTuple2, ImmutableTuple3, ImmutableTuple4};
-pub use tuple::{ImmutableTuple5, ImmutableTuple6, ImmutableTuple7, ImmutableTuple8};
-pub use tuple::{ImmutableTuple9, ImmutableTuple10, ImmutableTuple11, ImmutableTuple12};
-pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
-pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
-pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
-pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector};
-pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector};
-pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector};
-
-// Reexported runtime types
-pub use comm::{stream, Port, Chan, GenericChan, GenericSmartChan, GenericPort, Peekable};
-pub use task::spawn;
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unsafe pointer utility functions
-
-use cast;
-use clone::Clone;
-#[cfg(not(test))]
-use cmp::Equiv;
-use iter::{range, Iterator};
-use option::{Option, Some, None};
-use unstable::intrinsics;
-use util::swap;
-
-#[cfg(not(test))] use cmp::{Eq, Ord};
-
-/// Calculate the offset from a pointer
-#[inline]
-pub unsafe fn offset<T>(ptr: *T, count: int) -> *T {
- intrinsics::offset(ptr, count)
-}
-
-/// Calculate the offset from a mut pointer. The count *must* be in bounds or
-/// otherwise the loads of this address are undefined.
-#[inline]
-pub unsafe fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
- intrinsics::offset(ptr as *T, count) as *mut T
-}
-
-/// Return the offset of the first null pointer in `buf`.
-#[inline]
-pub unsafe fn buf_len<T>(buf: **T) -> uint {
- position(buf, |i| *i == null())
-}
-
-impl<T> Clone for *T {
- #[inline]
- fn clone(&self) -> *T {
- *self
- }
-}
-
-impl<T> Clone for *mut T {
- #[inline]
- fn clone(&self) -> *mut T {
- *self
- }
-}
-
-/// Return the first offset `i` such that `f(buf[i]) == true`.
-#[inline]
-pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
- let mut i = 0;
- loop {
- if f(&(*offset(buf, i as int))) { return i; }
- else { i += 1; }
- }
-}
-
-/// Create an unsafe null pointer
-#[inline]
-pub fn null<T>() -> *T { 0 as *T }
-
-/// Create an unsafe mutable null pointer
-#[inline]
-pub fn mut_null<T>() -> *mut T { 0 as *mut T }
-
-/// Returns true if the pointer is equal to the null pointer.
-#[inline]
-pub fn is_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_null() }
-
-/// Returns true if the pointer is not equal to the null pointer.
-#[inline]
-pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
-
-/**
- * Copies data from one location to another.
- *
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
- * and destination may overlap.
- */
-#[inline]
-pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
- intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count)
-}
-
-/**
- * Copies data from one location to another.
- *
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
- * and destination may *not* overlap.
- */
-#[inline]
-pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
- src: P,
- count: uint) {
- intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count)
-}
-
-/**
- * Invokes memset on the specified pointer, setting `count * size_of::<T>()`
- * bytes of memory starting at `dst` to `c`.
- */
-#[inline]
-pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
- intrinsics::set_memory(dst, c, count)
-}
-
-/**
- * Zeroes out `count * size_of::<T>` bytes of memory at `dst`
- */
-#[inline]
-pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
- set_memory(dst, 0, count);
-}
-
-/**
- * Swap the values at two mutable locations of the same type, without
- * deinitialising or copying either one.
- */
-#[inline]
-pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
- // Give ourselves some scratch space to work with
- let mut tmp: T = intrinsics::uninit();
- let t: *mut T = &mut tmp;
-
- // Perform the swap
- copy_nonoverlapping_memory(t, x, 1);
- copy_memory(x, y, 1); // `x` and `y` may overlap
- copy_nonoverlapping_memory(y, t, 1);
-
- // y and t now point to the same thing, but we need to completely forget `tmp`
- // because it's no longer relevant.
- cast::forget(tmp);
-}
-
-/**
- * Replace the value at a mutable location with a new one, returning the old
- * value, without deinitialising or copying either one.
- */
-#[inline]
-pub unsafe fn replace_ptr<T>(dest: *mut T, mut src: T) -> T {
- swap(cast::transmute(dest), &mut src); // cannot overlap
- src
-}
-
-/**
- * Reads the value from `*src` and returns it. Does not copy `*src`.
- */
-#[inline(always)]
-pub unsafe fn read_ptr<T>(src: *T) -> T {
- let mut tmp: T = intrinsics::uninit();
- copy_nonoverlapping_memory(&mut tmp, src, 1);
- tmp
-}
-
-/**
- * Reads the value from `*src` and nulls it out.
- * This currently prevents destructors from executing.
- */
-#[inline(always)]
-pub unsafe fn read_and_zero_ptr<T>(dest: *mut T) -> T {
- // Copy the data out from `dest`:
- let tmp = read_ptr(&*dest);
-
- // Now zero out `dest`:
- zero_memory(dest, 1);
-
- tmp
-}
-
-/// Transform a region pointer - &T - to an unsafe pointer - *T.
-#[inline]
-pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
- thing as *T
-}
-
-/// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
-#[inline]
-pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
- thing as *mut T
-}
-
-/**
- Given a **T (pointer to an array of pointers),
- iterate through each *T, up to the provided `len`,
- passing to the provided callback function
-
- SAFETY NOTE: Pointer-arithmetic. Dragons be here.
-*/
-pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
- debug!("array_each_with_len: before iterate");
- if (arr as uint == 0) {
- fail!("ptr::array_each_with_len failure: arr input is null pointer");
- }
- //let start_ptr = *arr;
- for e in range(0, len) {
- let n = offset(arr, e as int);
- cb(*n);
- }
- debug!("array_each_with_len: after iterate");
-}
-
-/**
- Given a null-pointer-terminated **T (pointer to
- an array of pointers), iterate through each *T,
- passing to the provided callback function
-
- SAFETY NOTE: This will only work with a null-terminated
- pointer array. Barely less-dodgy Pointer Arithmetic.
- Dragons be here.
-*/
-pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
- if (arr as uint == 0) {
- fail!("ptr::array_each_with_len failure: arr input is null pointer");
- }
- let len = buf_len(arr);
- debug!("array_each inferred len: {}", len);
- array_each_with_len(arr, len, cb);
-}
-
-#[allow(missing_doc)]
-pub trait RawPtr<T> {
- fn null() -> Self;
- fn is_null(&self) -> bool;
- fn is_not_null(&self) -> bool;
- fn to_uint(&self) -> uint;
- unsafe fn to_option(&self) -> Option<&T>;
- unsafe fn offset(self, count: int) -> Self;
-}
-
-/// Extension methods for immutable pointers
-impl<T> RawPtr<T> for *T {
- /// Returns the null pointer.
- #[inline]
- fn null() -> *T { null() }
-
- /// Returns true if the pointer is equal to the null pointer.
- #[inline]
- fn is_null(&self) -> bool { *self == RawPtr::null() }
-
- /// Returns true if the pointer is not equal to the null pointer.
- #[inline]
- fn is_not_null(&self) -> bool { *self != RawPtr::null() }
-
- /// Returns the address of this pointer.
- #[inline]
- fn to_uint(&self) -> uint { *self as uint }
-
- ///
- /// Returns `None` if the pointer is null, or else returns the value wrapped
- /// in `Some`.
- ///
- /// # Safety Notes
- ///
- /// While this method is useful for null-safety, it is important to note
- /// that this is still an unsafe operation because the returned value could
- /// be pointing to invalid memory.
- ///
- #[inline]
- unsafe fn to_option(&self) -> Option<&T> {
- if self.is_null() { None } else {
- Some(cast::transmute(*self))
- }
- }
-
- /// Calculates the offset from a pointer. The offset *must* be in-bounds of
- /// the object, or one-byte-past-the-end.
- #[inline]
- unsafe fn offset(self, count: int) -> *T { offset(self, count) }
-}
-
-/// Extension methods for mutable pointers
-impl<T> RawPtr<T> for *mut T {
- /// Returns the null pointer.
- #[inline]
- fn null() -> *mut T { mut_null() }
-
- /// Returns true if the pointer is equal to the null pointer.
- #[inline]
- fn is_null(&self) -> bool { *self == RawPtr::null() }
-
- /// Returns true if the pointer is not equal to the null pointer.
- #[inline]
- fn is_not_null(&self) -> bool { *self != RawPtr::null() }
-
- /// Returns the address of this pointer.
- #[inline]
- fn to_uint(&self) -> uint { *self as uint }
-
- ///
- /// Returns `None` if the pointer is null, or else returns the value wrapped
- /// in `Some`.
- ///
- /// # Safety Notes
- ///
- /// While this method is useful for null-safety, it is important to note
- /// that this is still an unsafe operation because the returned value could
- /// be pointing to invalid memory.
- ///
- #[inline]
- unsafe fn to_option(&self) -> Option<&T> {
- if self.is_null() { None } else {
- Some(cast::transmute(*self))
- }
- }
-
- /// Calculates the offset from a pointer. The offset *must* be in-bounds of
- /// the object, or one-byte-past-the-end. An arithmetic overflow is also
- /// undefined behaviour.
- ///
- /// This method should be preferred over `offset` when the guarantee can be
- /// satisfied, to enable better optimization.
- #[inline]
- unsafe fn offset(self, count: int) -> *mut T { mut_offset(self, count) }
-}
-
-// Equality for pointers
-#[cfg(not(test))]
-impl<T> Eq for *T {
- #[inline]
- fn eq(&self, other: &*T) -> bool {
- *self == *other
- }
- #[inline]
- fn ne(&self, other: &*T) -> bool { !self.eq(other) }
-}
-
-#[cfg(not(test))]
-impl<T> Eq for *mut T {
- #[inline]
- fn eq(&self, other: &*mut T) -> bool {
- *self == *other
- }
- #[inline]
- fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
-}
-
-// Equivalence for pointers
-#[cfg(not(test))]
-impl<T> Equiv<*mut T> for *T {
- fn equiv(&self, other: &*mut T) -> bool {
- self.to_uint() == other.to_uint()
- }
-}
-
-#[cfg(not(test))]
-impl<T> Equiv<*T> for *mut T {
- fn equiv(&self, other: &*T) -> bool {
- self.to_uint() == other.to_uint()
- }
-}
-
-// Equality for extern "C" fn pointers
-#[cfg(not(test))]
-mod externfnpointers {
- use cast;
- use cmp::Eq;
-
- impl<_R> Eq for extern "C" fn() -> _R {
- #[inline]
- fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
- let self_: *() = unsafe { cast::transmute(*self) };
- let other_: *() = unsafe { cast::transmute(*other) };
- self_ == other_
- }
- #[inline]
- fn ne(&self, other: &extern "C" fn() -> _R) -> bool {
- !self.eq(other)
- }
- }
- macro_rules! fnptreq(
- ($($p:ident),*) => {
- impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R {
- #[inline]
- fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
- let self_: *() = unsafe { cast::transmute(*self) };
- let other_: *() = unsafe { cast::transmute(*other) };
- self_ == other_
- }
- #[inline]
- fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
- !self.eq(other)
- }
- }
- }
- )
- fnptreq!(A)
- fnptreq!(A,B)
- fnptreq!(A,B,C)
- fnptreq!(A,B,C,D)
- fnptreq!(A,B,C,D,E)
-}
-
-// Comparison for pointers
-#[cfg(not(test))]
-impl<T> Ord for *T {
- #[inline]
- fn lt(&self, other: &*T) -> bool {
- *self < *other
- }
- #[inline]
- fn le(&self, other: &*T) -> bool {
- *self <= *other
- }
- #[inline]
- fn ge(&self, other: &*T) -> bool {
- *self >= *other
- }
- #[inline]
- fn gt(&self, other: &*T) -> bool {
- *self > *other
- }
-}
-
-#[cfg(not(test))]
-impl<T> Ord for *mut T {
- #[inline]
- fn lt(&self, other: &*mut T) -> bool {
- *self < *other
- }
- #[inline]
- fn le(&self, other: &*mut T) -> bool {
- *self <= *other
- }
- #[inline]
- fn ge(&self, other: &*mut T) -> bool {
- *self >= *other
- }
- #[inline]
- fn gt(&self, other: &*mut T) -> bool {
- *self > *other
- }
-}
-
-#[cfg(test)]
-pub mod ptr_tests {
- use super::*;
- use prelude::*;
-
- use c_str::ToCStr;
- use cast;
- use libc;
- use str;
- use vec;
-
- #[test]
- fn test() {
- unsafe {
- struct Pair {
- fst: int,
- snd: int
- };
- let mut p = Pair {fst: 10, snd: 20};
- let pptr: *mut Pair = &mut p;
- let iptr: *mut int = cast::transmute(pptr);
- assert_eq!(*iptr, 10);
- *iptr = 30;
- assert_eq!(*iptr, 30);
- assert_eq!(p.fst, 30);
-
- *pptr = Pair {fst: 50, snd: 60};
- assert_eq!(*iptr, 50);
- assert_eq!(p.fst, 50);
- assert_eq!(p.snd, 60);
-
- let v0 = ~[32000u16, 32001u16, 32002u16];
- let mut v1 = ~[0u16, 0u16, 0u16];
-
- copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1),
- offset(vec::raw::to_ptr(v0), 1), 1);
- assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
- copy_memory(vec::raw::to_mut_ptr(v1),
- offset(vec::raw::to_ptr(v0), 2), 1);
- assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
- v1[2] == 0u16));
- copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 2),
- vec::raw::to_ptr(v0), 1u);
- assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
- v1[2] == 32000u16));
- }
- }
-
- #[test]
- fn test_position() {
- use libc::c_char;
-
- "hello".with_c_str(|p| {
- unsafe {
- assert!(2u == position(p, |c| *c == 'l' as c_char));
- assert!(4u == position(p, |c| *c == 'o' as c_char));
- assert!(5u == position(p, |c| *c == 0 as c_char));
- }
- })
- }
-
- #[test]
- fn test_buf_len() {
- "hello".with_c_str(|p0| {
- "there".with_c_str(|p1| {
- "thing".with_c_str(|p2| {
- let v = ~[p0, p1, p2, null()];
- v.as_imm_buf(|vp, len| {
- assert_eq!(unsafe { buf_len(vp) }, 3u);
- assert_eq!(len, 4u);
- })
- })
- })
- })
- }
-
- #[test]
- fn test_is_null() {
- let p: *int = null();
- assert!(p.is_null());
- assert!(!p.is_not_null());
-
- let q = unsafe { offset(p, 1) };
- assert!(!q.is_null());
- assert!(q.is_not_null());
-
- let mp: *mut int = mut_null();
- assert!(mp.is_null());
- assert!(!mp.is_not_null());
-
- let mq = unsafe { mp.offset(1) };
- assert!(!mq.is_null());
- assert!(mq.is_not_null());
- }
-
- #[test]
- fn test_to_option() {
- unsafe {
- let p: *int = null();
- assert_eq!(p.to_option(), None);
-
- let q: *int = &2;
- assert_eq!(q.to_option().unwrap(), &2);
-
- let p: *mut int = mut_null();
- assert_eq!(p.to_option(), None);
-
- let q: *mut int = &mut 2;
- assert_eq!(q.to_option().unwrap(), &2);
- }
- }
-
- #[test]
- fn test_ptr_addition() {
- use vec::raw::*;
-
- unsafe {
- let xs = ~[5, ..16];
- let mut ptr = to_ptr(xs);
- let end = ptr.offset(16);
-
- while ptr < end {
- assert_eq!(*ptr, 5);
- ptr = ptr.offset(1);
- }
-
- let mut xs_mut = xs.clone();
- let mut m_ptr = to_mut_ptr(xs_mut);
- let m_end = m_ptr.offset(16);
-
- while m_ptr < m_end {
- *m_ptr += 5;
- m_ptr = m_ptr.offset(1);
- }
-
- assert_eq!(xs_mut, ~[10, ..16]);
- }
- }
-
- #[test]
- fn test_ptr_subtraction() {
- use vec::raw::*;
-
- unsafe {
- let xs = ~[0,1,2,3,4,5,6,7,8,9];
- let mut idx = 9i8;
- let ptr = to_ptr(xs);
-
- while idx >= 0i8 {
- assert_eq!(*(ptr.offset(idx as int)), idx as int);
- idx = idx - 1i8;
- }
-
- let mut xs_mut = xs.clone();
- let m_start = to_mut_ptr(xs_mut);
- let mut m_ptr = m_start.offset(9);
-
- while m_ptr >= m_start {
- *m_ptr += *m_ptr;
- m_ptr = m_ptr.offset(-1);
- }
-
- assert_eq!(xs_mut, ~[0,2,4,6,8,10,12,14,16,18]);
- }
- }
-
- #[test]
- fn test_ptr_array_each_with_len() {
- unsafe {
- let one = "oneOne".to_c_str();
- let two = "twoTwo".to_c_str();
- let three = "threeThree".to_c_str();
- let arr = ~[
- one.with_ref(|buf| buf),
- two.with_ref(|buf| buf),
- three.with_ref(|buf| buf),
- ];
- let expected_arr = [
- one, two, three
- ];
-
- arr.as_imm_buf(|arr_ptr, arr_len| {
- let mut ctr = 0;
- let mut iteration_count = 0;
- array_each_with_len(arr_ptr, arr_len, |e| {
- let actual = str::raw::from_c_str(e);
- let expected = expected_arr[ctr].with_ref(|buf| {
- str::raw::from_c_str(buf)
- });
- debug!(
- "test_ptr_array_each_with_len e: {}, a: {}",
- expected, actual);
- assert_eq!(actual, expected);
- ctr += 1;
- iteration_count += 1;
- });
- assert_eq!(iteration_count, 3u);
- })
- }
- }
-
- #[test]
- fn test_ptr_array_each() {
- unsafe {
- let one = "oneOne".to_c_str();
- let two = "twoTwo".to_c_str();
- let three = "threeThree".to_c_str();
- let arr = ~[
- one.with_ref(|buf| buf),
- two.with_ref(|buf| buf),
- three.with_ref(|buf| buf),
- // fake a null terminator
- null(),
- ];
- let expected_arr = [
- one, two, three
- ];
-
- arr.as_imm_buf(|arr_ptr, _| {
- let mut ctr = 0;
- let mut iteration_count = 0;
- array_each(arr_ptr, |e| {
- let actual = str::raw::from_c_str(e);
- let expected = expected_arr[ctr].with_ref(|buf| {
- str::raw::from_c_str(buf)
- });
- debug!(
- "test_ptr_array_each e: {}, a: {}",
- expected, actual);
- assert_eq!(actual, expected);
- ctr += 1;
- iteration_count += 1;
- });
- assert_eq!(iteration_count, 3);
- })
- }
- }
-
- #[test]
- #[should_fail]
- fn test_ptr_array_each_with_len_null_ptr() {
- unsafe {
- array_each_with_len(0 as **libc::c_char, 1, |e| {
- str::raw::from_c_str(e);
- });
- }
- }
- #[test]
- #[should_fail]
- fn test_ptr_array_each_null_ptr() {
- unsafe {
- array_each(0 as **libc::c_char, |e| {
- str::raw::from_c_str(e);
- });
- }
- }
-
- #[test]
- fn test_set_memory() {
- let mut xs = [0u8, ..20];
- let ptr = vec::raw::to_mut_ptr(xs);
- unsafe { set_memory(ptr, 5u8, xs.len()); }
- assert_eq!(xs, [5u8, ..20]);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The Gamma distribution.
-
-use rand::{Rng, Open01};
-use super::{IndependentSample, Sample, StandardNormal, Exp};
-use num;
-
-/// The Gamma distribution `Gamma(shape, scale)` distribution.
-///
-/// The density function of this distribution is
-///
-/// ```
-/// f(x) = x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
-/// ```
-///
-/// where `Γ` is the Gamma function, `k` is the shape and `θ` is the
-/// scale and both `k` and `θ` are strictly positive.
-///
-/// The algorithm used is that described by Marsaglia & Tsang 2000[1],
-/// falling back to directly sampling from an Exponential for `shape
-/// == 1`, and using the boosting technique described in [1] for
-/// `shape < 1`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{IndependentSample, Gamma};
-///
-/// fn main() {
-/// let gamma = Gamma::new(2.0, 5.0);
-/// let v = gamma.ind_sample(rand::task_rng());
-/// println!("{} is from a Gamma(2, 5) distribution", v);
-/// }
-/// ```
-///
-/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
-/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
-/// (September 2000),
-/// 363-372. DOI:[10.1145/358407.358414](http://doi.acm.org/10.1145/358407.358414)
-pub enum Gamma {
- priv Large(GammaLargeShape),
- priv One(Exp),
- priv Small(GammaSmallShape)
-}
-
-// These two helpers could be made public, but saving the
-// match-on-Gamma-enum branch from using them directly (e.g. if one
-// knows that the shape is always > 1) doesn't appear to be much
-// faster.
-
-/// Gamma distribution where the shape parameter is less than 1.
-///
-/// Note, samples from this require a compulsory floating-point `pow`
-/// call, which makes it significantly slower than sampling from a
-/// gamma distribution where the shape parameter is greater than or
-/// equal to 1.
-///
-/// See `Gamma` for sampling from a Gamma distribution with general
-/// shape parameters.
-struct GammaSmallShape {
- inv_shape: f64,
- large_shape: GammaLargeShape
-}
-
-/// Gamma distribution where the shape parameter is larger than 1.
-///
-/// See `Gamma` for sampling from a Gamma distribution with general
-/// shape parameters.
-struct GammaLargeShape {
- shape: f64,
- scale: f64,
- c: f64,
- d: f64
-}
-
-impl Gamma {
- /// Construct an object representing the `Gamma(shape, scale)`
- /// distribution.
- ///
- /// Fails if `shape <= 0` or `scale <= 0`.
- pub fn new(shape: f64, scale: f64) -> Gamma {
- assert!(shape > 0.0, "Gamma::new called with shape <= 0");
- assert!(scale > 0.0, "Gamma::new called with scale <= 0");
-
- match shape {
- 1.0 => One(Exp::new(1.0 / scale)),
- 0.0 .. 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
- _ => Large(GammaLargeShape::new_raw(shape, scale))
- }
- }
-}
-
-impl GammaSmallShape {
- fn new_raw(shape: f64, scale: f64) -> GammaSmallShape {
- GammaSmallShape {
- inv_shape: 1. / shape,
- large_shape: GammaLargeShape::new_raw(shape + 1.0, scale)
- }
- }
-}
-
-impl GammaLargeShape {
- fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
- let d = shape - 1. / 3.;
- GammaLargeShape {
- shape: shape,
- scale: scale,
- c: 1. / num::sqrt(9. * d),
- d: d
- }
- }
-}
-
-impl Sample<f64> for Gamma {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl Sample<f64> for GammaSmallShape {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl Sample<f64> for GammaLargeShape {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-
-impl IndependentSample<f64> for Gamma {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
- match *self {
- Small(ref g) => g.ind_sample(rng),
- One(ref g) => g.ind_sample(rng),
- Large(ref g) => g.ind_sample(rng),
- }
- }
-}
-impl IndependentSample<f64> for GammaSmallShape {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
- let u = *rng.gen::<Open01<f64>>();
-
- self.large_shape.ind_sample(rng) * num::pow(u, self.inv_shape)
- }
-}
-impl IndependentSample<f64> for GammaLargeShape {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
- loop {
- let x = *rng.gen::<StandardNormal>();
- let v_cbrt = 1.0 + self.c * x;
- if v_cbrt <= 0.0 { // a^3 <= 0 iff a <= 0
- continue
- }
-
- let v = v_cbrt * v_cbrt * v_cbrt;
- let u = *rng.gen::<Open01<f64>>();
-
- let x_sqr = x * x;
- if u < 1.0 - 0.0331 * x_sqr * x_sqr ||
- num::ln(u) < 0.5 * x_sqr + self.d * (1.0 - v + num::ln(v)) {
- return self.d * v * self.scale
- }
- }
- }
-}
-
-#[cfg(test)]
-mod bench {
- use super::*;
- use mem::size_of;
- use rand::distributions::IndependentSample;
- use rand::{StdRng, RAND_BENCH_N};
- use extra::test::BenchHarness;
- use iter::range;
- use option::{Some, None};
-
-
- #[bench]
- fn bench_gamma_large_shape(bh: &mut BenchHarness) {
- let gamma = Gamma::new(10., 1.0);
- let mut rng = StdRng::new();
-
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- gamma.ind_sample(&mut rng);
- }
- });
- bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
- }
-
- #[bench]
- fn bench_gamma_small_shape(bh: &mut BenchHarness) {
- let gamma = Gamma::new(0.1, 1.0);
- let mut rng = StdRng::new();
-
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- gamma.ind_sample(&mut rng);
- }
- });
- bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Sampling from random distributions.
-
-This is a generalization of `Rand` to allow parameters to control the
-exact properties of the generated values, e.g. the mean and standard
-deviation of a normal distribution. The `Sample` trait is the most
-general, and allows for generating values that change some state
-internally. The `IndependentSample` trait is for generating values
-that do not need to record state.
-
-*/
-
-use iter::range;
-use option::{Some, None};
-use num;
-use rand::{Rng, Rand, Open01};
-use clone::Clone;
-
-pub use self::range::Range;
-pub use self::gamma::Gamma;
-
-pub mod range;
-pub mod gamma;
-
-/// Types that can be used to create a random instance of `Support`.
-pub trait Sample<Support> {
- /// Generate a random value of `Support`, using `rng` as the
- /// source of randomness.
- fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
-}
-
-/// `Sample`s that do not require keeping track of state.
-///
-/// Since no state is recored, each sample is (statistically)
-/// independent of all others, assuming the `Rng` used has this
-/// property.
-// XXX maybe having this separate is overkill (the only reason is to
-// take &self rather than &mut self)? or maybe this should be the
-// trait called `Sample` and the other should be `DependentSample`.
-pub trait IndependentSample<Support>: Sample<Support> {
- /// Generate a random value.
- fn ind_sample<R: Rng>(&self, &mut R) -> Support;
-}
-
-/// A wrapper for generating types that implement `Rand` via the
-/// `Sample` & `IndependentSample` traits.
-pub struct RandSample<Sup>;
-
-impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
-}
-
-impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
- rng.gen()
- }
-}
-
-/// A value with a particular weight for use with `WeightedChoice`.
-pub struct Weighted<T> {
- /// The numerical weight of this item
- weight: uint,
- /// The actual item which is being weighted
- item: T,
-}
-
-/// A distribution that selects from a finite collection of weighted items.
-///
-/// Each item has an associated weight that influences how likely it
-/// is to be chosen: higher weight is more likely.
-///
-/// The `Clone` restriction is a limitation of the `Sample` and
-/// `IndepedentSample` traits. Note that `&T` is (cheaply) `Clone` for
-/// all `T`, as is `uint`, so one can store references or indices into
-/// another vector.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{Weighted, WeightedChoice, IndepedentSample};
-///
-/// fn main() {
-/// let wc = WeightedChoice::new(~[Weighted { weight: 2, item: 'a' },
-/// Weighted { weight: 4, item: 'b' },
-/// Weighted { weight: 1, item: 'c' }]);
-/// let rng = rand::task_rng();
-/// for _ in range(0, 16) {
-/// // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
-/// println!("{}", wc.ind_sample(rng));
-/// }
-/// }
-/// ```
-pub struct WeightedChoice<T> {
- priv items: ~[Weighted<T>],
- priv weight_range: Range<uint>
-}
-
-impl<T: Clone> WeightedChoice<T> {
- /// Create a new `WeightedChoice`.
- ///
- /// Fails if:
- /// - `v` is empty
- /// - the total weight is 0
- /// - the total weight is larger than a `uint` can contain.
- pub fn new(mut items: ~[Weighted<T>]) -> WeightedChoice<T> {
- // strictly speaking, this is subsumed by the total weight == 0 case
- assert!(!items.is_empty(), "WeightedChoice::new called with no items");
-
- let mut running_total = 0u;
-
- // we convert the list from individual weights to cumulative
- // weights so we can binary search. This *could* drop elements
- // with weight == 0 as an optimisation.
- for item in items.mut_iter() {
- running_total = running_total.checked_add(&item.weight)
- .expect("WeightedChoice::new called with a total weight larger \
- than a uint can contain");
-
- item.weight = running_total;
- }
- assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");
-
- WeightedChoice {
- items: items,
- // we're likely to be generating numbers in this range
- // relatively often, so might as well cache it
- weight_range: Range::new(0, running_total)
- }
- }
-}
-
-impl<T: Clone> Sample<T> for WeightedChoice<T> {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
-}
-
-impl<T: Clone> IndependentSample<T> for WeightedChoice<T> {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
- // we want to find the first element that has cumulative
- // weight > sample_weight, which we do by binary since the
- // cumulative weights of self.items are sorted.
-
- // choose a weight in [0, total_weight)
- let sample_weight = self.weight_range.ind_sample(rng);
-
- // short circuit when it's the first item
- if sample_weight < self.items[0].weight {
- return self.items[0].item.clone();
- }
-
- let mut idx = 0;
- let mut modifier = self.items.len();
-
- // now we know that every possibility has an element to the
- // left, so we can just search for the last element that has
- // cumulative weight <= sample_weight, then the next one will
- // be "it". (Note that this greatest element will never be the
- // last element of the vector, since sample_weight is chosen
- // in [0, total_weight) and the cumulative weight of the last
- // one is exactly the total weight.)
- while modifier > 1 {
- let i = idx + modifier / 2;
- if self.items[i].weight <= sample_weight {
- // we're small, so look to the right, but allow this
- // exact element still.
- idx = i;
- // we need the `/ 2` to round up otherwise we'll drop
- // the trailing elements when `modifier` is odd.
- modifier += 1;
- } else {
- // otherwise we're too big, so go left. (i.e. do
- // nothing)
- }
- modifier /= 2;
- }
- return self.items[idx + 1].item.clone();
- }
-}
-
-mod ziggurat_tables;
-
-/// Sample a random number using the Ziggurat method (specifically the
-/// ZIGNOR variant from Doornik 2005). Most of the arguments are
-/// directly from the paper:
-///
-/// * `rng`: source of randomness
-/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
-/// * `X`: the $x_i$ abscissae.
-/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
-/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
-/// * `pdf`: the probability density function
-/// * `zero_case`: manual sampling from the tail when we chose the
-/// bottom box (i.e. i == 0)
-
-// the perf improvement (25-50%) is definitely worth the extra code
-// size from force-inlining.
-#[inline(always)]
-fn ziggurat<R:Rng>(
- rng: &mut R,
- symmetric: bool,
- X: ziggurat_tables::ZigTable,
- F: ziggurat_tables::ZigTable,
- pdf: 'static |f64| -> f64,
- zero_case: 'static |&mut R, f64| -> f64)
- -> f64 {
- static SCALE: f64 = (1u64 << 53) as f64;
- loop {
- // reimplement the f64 generation as an optimisation suggested
- // by the Doornik paper: we have a lot of precision-space
- // (i.e. there are 11 bits of the 64 of a u64 to use after
- // creating a f64), so we might as well reuse some to save
- // generating a whole extra random number. (Seems to be 15%
- // faster.)
- let bits: u64 = rng.gen();
- let i = (bits & 0xff) as uint;
- let f = (bits >> 11) as f64 / SCALE;
-
- // u is either U(-1, 1) or U(0, 1) depending on if this is a
- // symmetric distribution or not.
- let u = if symmetric {2.0 * f - 1.0} else {f};
- let x = u * X[i];
-
- let test_x = if symmetric {num::abs(x)} else {x};
-
- // algebraically equivalent to |u| < X[i+1]/X[i] (or u < X[i+1]/X[i])
- if test_x < X[i + 1] {
- return x;
- }
- if i == 0 {
- return zero_case(rng, u);
- }
- // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
- if F[i + 1] + (F[i] - F[i + 1]) * rng.gen() < pdf(x) {
- return x;
- }
- }
-}
-
-/// A wrapper around an `f64` to generate N(0, 1) random numbers
-/// (a.k.a. a standard normal, or Gaussian).
-///
-/// See `Normal` for the general normal distribution. That this has to
-/// be unwrapped before use as an `f64` (using either `*` or
-/// `cast::transmute` is safe).
-///
-/// Implemented via the ZIGNOR variant[1] of the Ziggurat method.
-///
-/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
-/// Generate Normal Random
-/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
-/// College, Oxford
-pub struct StandardNormal(f64);
-
-impl Rand for StandardNormal {
- fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
- #[inline]
- fn pdf(x: f64) -> f64 {
- ((-x*x/2.0) as f64).exp()
- }
- #[inline]
- fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
- // compute a random number in the tail by hand
-
- // strange initial conditions, because the loop is not
- // do-while, so the condition should be true on the first
- // run, they get overwritten anyway (0 < 1, so these are
- // good).
- let mut x = 1.0f64;
- let mut y = 0.0f64;
-
- while -2.0 * y < x * x {
- let x_ = *rng.gen::<Open01<f64>>();
- let y_ = *rng.gen::<Open01<f64>>();
-
- x = x_.ln() / ziggurat_tables::ZIG_NORM_R;
- y = y_.ln();
- }
-
- if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
- }
-
- StandardNormal(ziggurat(
- rng,
- true, // this is symmetric
- &ziggurat_tables::ZIG_NORM_X,
- &ziggurat_tables::ZIG_NORM_F,
- pdf, zero_case))
- }
-}
-
-/// The normal distribution `N(mean, std_dev**2)`.
-///
-/// This uses the ZIGNOR variant of the Ziggurat method, see
-/// `StandardNormal` for more details.
-///
-/// # Example
-///
-/// ```
-/// use std::rand;
-/// use std::rand::distributions::{Normal, IndependentSample};
-///
-/// fn main() {
-/// let normal = Normal::new(2.0, 3.0);
-/// let v = normal.ind_sample(rand::task_rng());
-/// println!("{} is from a N(2, 9) distribution", v)
-/// }
-/// ```
-pub struct Normal {
- priv mean: f64,
- priv std_dev: f64
-}
-
-impl Normal {
- /// Construct a new `Normal` distribution with the given mean and
- /// standard deviation. Fails if `std_dev < 0`.
- pub fn new(mean: f64, std_dev: f64) -> Normal {
- assert!(std_dev >= 0.0, "Normal::new called with `std_dev` < 0");
- Normal {
- mean: mean,
- std_dev: std_dev
- }
- }
-}
-impl Sample<f64> for Normal {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for Normal {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
- self.mean + self.std_dev * (*rng.gen::<StandardNormal>())
- }
-}
-
-/// A wrapper around an `f64` to generate Exp(1) random numbers.
-///
-/// See `Exp` for the general exponential distribution.Note that this
- // has to be unwrapped before use as an `f64` (using either
-/// `*` or `cast::transmute` is safe).
-///
-/// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The
-/// exact description in the paper was adjusted to use tables for the
-/// exponential distribution rather than normal.
-///
-/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
-/// Generate Normal Random
-/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
-/// College, Oxford
-pub struct Exp1(f64);
-
-// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
-impl Rand for Exp1 {
- #[inline]
- fn rand<R:Rng>(rng: &mut R) -> Exp1 {
- #[inline]
- fn pdf(x: f64) -> f64 {
- (-x).exp()
- }
- #[inline]
- fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
- ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
- }
-
- Exp1(ziggurat(rng, false,
- &ziggurat_tables::ZIG_EXP_X,
- &ziggurat_tables::ZIG_EXP_F,
- pdf, zero_case))
- }
-}
-
-/// The exponential distribution `Exp(lambda)`.
-///
-/// This distribution has density function: `f(x) = lambda *
-/// exp(-lambda * x)` for `x > 0`.
-///
-/// # Example
-///
-/// ```
-/// use std::rand;
-/// use std::rand::distributions::{Exp, IndependentSample};
-///
-/// fn main() {
-/// let exp = Exp::new(2.0);
-/// let v = exp.ind_sample(rand::task_rng());
-/// println!("{} is from a Exp(2) distribution", v);
-/// }
-/// ```
-pub struct Exp {
- /// `lambda` stored as `1/lambda`, since this is what we scale by.
- priv lambda_inverse: f64
-}
-
-impl Exp {
- /// Construct a new `Exp` with the given shape parameter
- /// `lambda`. Fails if `lambda <= 0`.
- pub fn new(lambda: f64) -> Exp {
- assert!(lambda > 0.0, "Exp::new called with `lambda` <= 0");
- Exp { lambda_inverse: 1.0 / lambda }
- }
-}
-
-impl Sample<f64> for Exp {
- fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for Exp {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
- (*rng.gen::<Exp1>()) * self.lambda_inverse
- }
-}
-
-#[cfg(test)]
-mod tests {
- use rand::*;
- use super::*;
- use iter::range;
- use option::{Some, None};
-
- struct ConstRand(uint);
- impl Rand for ConstRand {
- fn rand<R: Rng>(_: &mut R) -> ConstRand {
- ConstRand(0)
- }
- }
-
- // 0, 1, 2, 3, ...
- struct CountingRng { i: u32 }
- impl Rng for CountingRng {
- fn next_u32(&mut self) -> u32 {
- self.i += 1;
- self.i - 1
- }
- fn next_u64(&mut self) -> u64 {
- self.next_u32() as u64
- }
- }
-
- #[test]
- fn test_rand_sample() {
- let mut rand_sample = RandSample::<ConstRand>;
-
- assert_eq!(*rand_sample.sample(&mut task_rng()), 0);
- assert_eq!(*rand_sample.ind_sample(&mut task_rng()), 0);
- }
-
- #[test]
- fn test_normal() {
- let mut norm = Normal::new(10.0, 10.0);
- let mut rng = task_rng();
- for _ in range(0, 1000) {
- norm.sample(&mut rng);
- norm.ind_sample(&mut rng);
- }
- }
- #[test]
- #[should_fail]
- fn test_normal_invalid_sd() {
- Normal::new(10.0, -1.0);
- }
-
- #[test]
- fn test_exp() {
- let mut exp = Exp::new(10.0);
- let mut rng = task_rng();
- for _ in range(0, 1000) {
- assert!(exp.sample(&mut rng) >= 0.0);
- assert!(exp.ind_sample(&mut rng) >= 0.0);
- }
- }
- #[test]
- #[should_fail]
- fn test_exp_invalid_lambda_zero() {
- Exp::new(0.0);
- }
- #[test]
- #[should_fail]
- fn test_exp_invalid_lambda_neg() {
- Exp::new(-10.0);
- }
-
- #[test]
- fn test_weighted_choice() {
- // this makes assumptions about the internal implementation of
- // WeightedChoice, specifically: it doesn't reorder the items,
- // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
- // 1, internally; modulo a modulo operation).
-
- macro_rules! t (
- ($items:expr, $expected:expr) => {{
- let wc = WeightedChoice::new($items);
- let expected = $expected;
-
- let mut rng = CountingRng { i: 0 };
-
- for &val in expected.iter() {
- assert_eq!(wc.ind_sample(&mut rng), val)
- }
- }}
- );
-
- t!(~[Weighted { weight: 1, item: 10}], ~[10]);
-
- // skip some
- t!(~[Weighted { weight: 0, item: 20},
- Weighted { weight: 2, item: 21},
- Weighted { weight: 0, item: 22},
- Weighted { weight: 1, item: 23}],
- ~[21,21, 23]);
-
- // different weights
- t!(~[Weighted { weight: 4, item: 30},
- Weighted { weight: 3, item: 31}],
- ~[30,30,30,30, 31,31,31]);
-
- // check that we're binary searching
- // correctly with some vectors of odd
- // length.
- t!(~[Weighted { weight: 1, item: 40},
- Weighted { weight: 1, item: 41},
- Weighted { weight: 1, item: 42},
- Weighted { weight: 1, item: 43},
- Weighted { weight: 1, item: 44}],
- ~[40, 41, 42, 43, 44]);
- t!(~[Weighted { weight: 1, item: 50},
- Weighted { weight: 1, item: 51},
- Weighted { weight: 1, item: 52},
- Weighted { weight: 1, item: 53},
- Weighted { weight: 1, item: 54},
- Weighted { weight: 1, item: 55},
- Weighted { weight: 1, item: 56}],
- ~[50, 51, 52, 53, 54, 55, 56]);
- }
-
- #[test] #[should_fail]
- fn test_weighted_choice_no_items() {
- WeightedChoice::<int>::new(~[]);
- }
- #[test] #[should_fail]
- fn test_weighted_choice_zero_weight() {
- WeightedChoice::new(~[Weighted { weight: 0, item: 0},
- Weighted { weight: 0, item: 1}]);
- }
- #[test] #[should_fail]
- fn test_weighted_choice_weight_overflows() {
- let x = (-1) as uint / 2; // x + x + 2 is the overflow
- WeightedChoice::new(~[Weighted { weight: x, item: 0 },
- Weighted { weight: 1, item: 1 },
- Weighted { weight: x, item: 2 },
- Weighted { weight: 1, item: 3 }]);
- }
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
- use rand::{XorShiftRng, RAND_BENCH_N};
- use super::*;
- use iter::range;
- use option::{Some, None};
- use mem::size_of;
-
- #[bench]
- fn rand_normal(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new();
- let mut normal = Normal::new(-2.71828, 3.14159);
-
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- normal.sample(&mut rng);
- }
- });
- bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
- }
- #[bench]
- fn rand_exp(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new();
- let mut exp = Exp::new(2.71828 * 3.14159);
-
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- exp.sample(&mut rng);
- }
- });
- bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Generating numbers between two others.
-
-// this is surprisingly complicated to be both generic & correct
-
-use cmp::Ord;
-use num::Bounded;
-use rand::Rng;
-use rand::distributions::{Sample, IndependentSample};
-
-/// Sample values uniformly between two bounds.
-///
-/// This gives a uniform distribution (assuming the RNG used to sample
-/// it is itself uniform & the `SampleRange` implementation for the
-/// given type is correct), even for edge cases like `low = 0u8`,
-/// `high = 170u8`, for which a naive modulo operation would return
-/// numbers less than 85 with double the probability to those greater
-/// than 85.
-///
-/// Types should attempt to sample in `[low, high)`, i.e., not
-/// including `high`, but this may be very difficult. All the
-/// primitive integer types satisfy this property, and the float types
-/// normally satisfy it, but rounding may mean `high` can occur.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{IndependentSample, Range};
-///
-/// fn main() {
-/// let between = Range::new(10u, 10000u);
-/// let rng = rand::task_rng();
-/// let mut sum = 0;
-/// for _ in range(0, 1000) {
-/// sum += between.ind_sample(rng);
-/// }
-/// println!("{}", sum);
-/// }
-/// ```
-pub struct Range<X> {
- priv low: X,
- priv range: X,
- priv accept_zone: X
-}
-
-impl<X: SampleRange + Ord> Range<X> {
- /// Create a new `Range` instance that samples uniformly from
- /// `[low, high)`. Fails if `low >= high`.
- pub fn new(low: X, high: X) -> Range<X> {
- assert!(low < high, "Range::new called with `low >= high`");
- SampleRange::construct_range(low, high)
- }
-}
-
-impl<Sup: SampleRange> Sample<Sup> for Range<Sup> {
- #[inline]
- fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
-}
-impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
- fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
- SampleRange::sample_range(self, rng)
- }
-}
-
-/// The helper trait for types that have a sensible way to sample
-/// uniformly between two values. This should not be used directly,
-/// and is only to facilitate `Range`.
-pub trait SampleRange {
- /// Construct the `Range` object that `sample_range`
- /// requires. This should not ever be called directly, only via
- /// `Range::new`, which will check that `low < high`, so this
- /// function doesn't have to repeat the check.
- fn construct_range(low: Self, high: Self) -> Range<Self>;
-
- /// Sample a value from the given `Range` with the given `Rng` as
- /// a source of randomness.
- fn sample_range<R: Rng>(r: &Range<Self>, rng: &mut R) -> Self;
-}
-
-macro_rules! integer_impl {
- ($ty:ty, $unsigned:ty) => {
- impl SampleRange for $ty {
- // we play free and fast with unsigned vs signed here
- // (when $ty is signed), but that's fine, since the
- // contract of this macro is for $ty and $unsigned to be
- // "bit-equal", so casting between them is a no-op & a
- // bijection.
-
- fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
- let range = high as $unsigned - low as $unsigned;
- let unsigned_max: $unsigned = Bounded::max_value();
-
- // this is the largest number that fits into $unsigned
- // that `range` divides evenly, so, if we've sampled
- // `n` uniformly from this region, then `n % range` is
- // uniform in [0, range)
- let zone = unsigned_max - unsigned_max % range;
-
- Range {
- low: low,
- range: range as $ty,
- accept_zone: zone as $ty
- }
- }
- #[inline]
- fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
- loop {
- // rejection sample
- let v = rng.gen::<$unsigned>();
- // until we find something that fits into the
- // region which r.range evenly divides (this will
- // be uniformly distributed)
- if v < r.accept_zone as $unsigned {
- // and return it, with some adjustments
- return r.low + (v % r.range as $unsigned) as $ty;
- }
- }
- }
- }
- }
-}
-
-integer_impl! { i8, u8 }
-integer_impl! { i16, u16 }
-integer_impl! { i32, u32 }
-integer_impl! { i64, u64 }
-integer_impl! { int, uint }
-integer_impl! { u8, u8 }
-integer_impl! { u16, u16 }
-integer_impl! { u32, u32 }
-integer_impl! { u64, u64 }
-integer_impl! { uint, uint }
-
-macro_rules! float_impl {
- ($ty:ty) => {
- impl SampleRange for $ty {
- fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
- Range {
- low: low,
- range: high - low,
- accept_zone: 0.0 // unused
- }
- }
- fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
- r.low + r.range * rng.gen()
- }
- }
- }
-}
-
-float_impl! { f32 }
-float_impl! { f64 }
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use rand::*;
- use num::Bounded;
- use iter::range;
- use option::{Some, None};
- use vec::ImmutableVector;
-
- #[should_fail]
- #[test]
- fn test_range_bad_limits_equal() {
- Range::new(10, 10);
- }
- #[should_fail]
- #[test]
- fn test_range_bad_limits_flipped() {
- Range::new(10, 5);
- }
-
- #[test]
- fn test_integers() {
- let mut rng = task_rng();
- macro_rules! t (
- ($($ty:ty),*) => {{
- $(
- let v: &[($ty, $ty)] = [(0, 10),
- (10, 127),
- (Bounded::min_value(), Bounded::max_value())];
- for &(low, high) in v.iter() {
- let mut sampler: Range<$ty> = Range::new(low, high);
- for _ in range(0, 1000) {
- let v = sampler.sample(&mut rng);
- assert!(low <= v && v < high);
- let v = sampler.ind_sample(&mut rng);
- assert!(low <= v && v < high);
- }
- }
- )*
- }}
- );
- t!(i8, i16, i32, i64, int,
- u8, u16, u32, u64, uint)
- }
-
- #[test]
- fn test_floats() {
- let mut rng = task_rng();
- macro_rules! t (
- ($($ty:ty),*) => {{
- $(
- let v: &[($ty, $ty)] = [(0.0, 100.0),
- (-1e35, -1e25),
- (1e-35, 1e-25),
- (-1e35, 1e35)];
- for &(low, high) in v.iter() {
- let mut sampler: Range<$ty> = Range::new(low, high);
- for _ in range(0, 1000) {
- let v = sampler.sample(&mut rng);
- assert!(low <= v && v < high);
- let v = sampler.ind_sample(&mut rng);
- assert!(low <= v && v < high);
- }
- }
- )*
- }}
- );
-
- t!(f32, f64)
- }
-
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tables for distributions which are sampled using the ziggurat
-// algorithm. Autogenerated by `ziggurat_tables.py`.
-
-pub type ZigTable = &'static [f64, .. 257];
-pub static ZIG_NORM_R: f64 = 3.654152885361008796;
-pub static ZIG_NORM_X: [f64, .. 257] =
- [3.910757959537090045, 3.654152885361008796, 3.449278298560964462, 3.320244733839166074,
- 3.224575052047029100, 3.147889289517149969, 3.083526132001233044, 3.027837791768635434,
- 2.978603279880844834, 2.934366867207854224, 2.894121053612348060, 2.857138730872132548,
- 2.822877396825325125, 2.790921174000785765, 2.760944005278822555, 2.732685359042827056,
- 2.705933656121858100, 2.680514643284522158, 2.656283037575502437, 2.633116393630324570,
- 2.610910518487548515, 2.589575986706995181, 2.569035452680536569, 2.549221550323460761,
- 2.530075232158516929, 2.511544441625342294, 2.493583041269680667, 2.476149939669143318,
- 2.459208374333311298, 2.442725318198956774, 2.426670984935725972, 2.411018413899685520,
- 2.395743119780480601, 2.380822795170626005, 2.366237056715818632, 2.351967227377659952,
- 2.337996148795031370, 2.324308018869623016, 2.310888250599850036, 2.297723348901329565,
- 2.284800802722946056, 2.272108990226823888, 2.259637095172217780, 2.247375032945807760,
- 2.235313384928327984, 2.223443340090905718, 2.211756642882544366, 2.200245546609647995,
- 2.188902771624720689, 2.177721467738641614, 2.166695180352645966, 2.155817819875063268,
- 2.145083634046203613, 2.134487182844320152, 2.124023315687815661, 2.113687150684933957,
- 2.103474055713146829, 2.093379631137050279, 2.083399693996551783, 2.073530263516978778,
- 2.063767547809956415, 2.054107931648864849, 2.044547965215732788, 2.035084353727808715,
- 2.025713947862032960, 2.016433734904371722, 2.007240830558684852, 1.998132471356564244,
- 1.989106007615571325, 1.980158896898598364, 1.971288697931769640, 1.962493064942461896,
- 1.953769742382734043, 1.945116560006753925, 1.936531428273758904, 1.928012334050718257,
- 1.919557336591228847, 1.911164563769282232, 1.902832208548446369, 1.894558525668710081,
- 1.886341828534776388, 1.878180486290977669, 1.870072921069236838, 1.862017605397632281,
- 1.854013059758148119, 1.846057850283119750, 1.838150586580728607, 1.830289919680666566,
- 1.822474540091783224, 1.814703175964167636, 1.806974591348693426, 1.799287584547580199,
- 1.791640986550010028, 1.784033659547276329, 1.776464495522344977, 1.768932414909077933,
- 1.761436365316706665, 1.753975320315455111, 1.746548278279492994, 1.739154261283669012,
- 1.731792314050707216, 1.724461502945775715, 1.717160915015540690, 1.709889657069006086,
- 1.702646854797613907, 1.695431651932238548, 1.688243209434858727, 1.681080704722823338,
- 1.673943330923760353, 1.666830296159286684, 1.659740822855789499, 1.652674147080648526,
- 1.645629517902360339, 1.638606196773111146, 1.631603456932422036, 1.624620582830568427,
- 1.617656869570534228, 1.610711622367333673, 1.603784156023583041, 1.596873794420261339,
- 1.589979870021648534, 1.583101723393471438, 1.576238702733332886, 1.569390163412534456,
- 1.562555467528439657, 1.555733983466554893, 1.548925085471535512, 1.542128153226347553,
- 1.535342571438843118, 1.528567729435024614, 1.521803020758293101, 1.515047842773992404,
- 1.508301596278571965, 1.501563685112706548, 1.494833515777718391, 1.488110497054654369,
- 1.481394039625375747, 1.474683555695025516, 1.467978458615230908, 1.461278162507407830,
- 1.454582081885523293, 1.447889631277669675, 1.441200224845798017, 1.434513276002946425,
- 1.427828197027290358, 1.421144398672323117, 1.414461289772464658, 1.407778276843371534,
- 1.401094763676202559, 1.394410150925071257, 1.387723835686884621, 1.381035211072741964,
- 1.374343665770030531, 1.367648583594317957, 1.360949343030101844, 1.354245316759430606,
- 1.347535871177359290, 1.340820365893152122, 1.334098153216083604, 1.327368577624624679,
- 1.320630975217730096, 1.313884673146868964, 1.307128989027353860, 1.300363230327433728,
- 1.293586693733517645, 1.286798664489786415, 1.279998415710333237, 1.273185207661843732,
- 1.266358287014688333, 1.259516886060144225, 1.252660221891297887, 1.245787495544997903,
- 1.238897891102027415, 1.231990574742445110, 1.225064693752808020, 1.218119375481726552,
- 1.211153726239911244, 1.204166830140560140, 1.197157747875585931, 1.190125515422801650,
- 1.183069142678760732, 1.175987612011489825, 1.168879876726833800, 1.161744859441574240,
- 1.154581450355851802, 1.147388505416733873, 1.140164844363995789, 1.132909248648336975,
- 1.125620459211294389, 1.118297174115062909, 1.110938046009249502, 1.103541679420268151,
- 1.096106627847603487, 1.088631390649514197, 1.081114409698889389, 1.073554065787871714,
- 1.065948674757506653, 1.058296483326006454, 1.050595664586207123, 1.042844313139370538,
- 1.035040439828605274, 1.027181966030751292, 1.019266717460529215, 1.011292417434978441,
- 1.003256679539591412, 0.995156999629943084, 0.986990747093846266, 0.978755155288937750,
- 0.970447311058864615, 0.962064143217605250, 0.953602409875572654, 0.945058684462571130,
- 0.936429340280896860, 0.927710533396234771, 0.918898183643734989, 0.909987953490768997,
- 0.900975224455174528, 0.891855070726792376, 0.882622229578910122, 0.873271068082494550,
- 0.863795545546826915, 0.854189171001560554, 0.844444954902423661, 0.834555354079518752,
- 0.824512208745288633, 0.814306670128064347, 0.803929116982664893, 0.793369058833152785,
- 0.782615023299588763, 0.771654424216739354, 0.760473406422083165, 0.749056662009581653,
- 0.737387211425838629, 0.725446140901303549, 0.713212285182022732, 0.700661841097584448,
- 0.687767892786257717, 0.674499822827436479, 0.660822574234205984, 0.646695714884388928,
- 0.632072236375024632, 0.616896989996235545, 0.601104617743940417, 0.584616766093722262,
- 0.567338257040473026, 0.549151702313026790, 0.529909720646495108, 0.509423329585933393,
- 0.487443966121754335, 0.463634336771763245, 0.437518402186662658, 0.408389134588000746,
- 0.375121332850465727, 0.335737519180459465, 0.286174591747260509, 0.215241895913273806,
- 0.000000000000000000];
-pub static ZIG_NORM_F: [f64, .. 257] =
- [0.000477467764586655, 0.001260285930498598, 0.002609072746106363, 0.004037972593371872,
- 0.005522403299264754, 0.007050875471392110, 0.008616582769422917, 0.010214971439731100,
- 0.011842757857943104, 0.013497450601780807, 0.015177088307982072, 0.016880083152595839,
- 0.018605121275783350, 0.020351096230109354, 0.022117062707379922, 0.023902203305873237,
- 0.025705804008632656, 0.027527235669693315, 0.029365939758230111, 0.031221417192023690,
- 0.033093219458688698, 0.034980941461833073, 0.036884215688691151, 0.038802707404656918,
- 0.040736110656078753, 0.042684144916619378, 0.044646552251446536, 0.046623094902089664,
- 0.048613553216035145, 0.050617723861121788, 0.052635418276973649, 0.054666461325077916,
- 0.056710690106399467, 0.058767952921137984, 0.060838108349751806, 0.062921024437977854,
- 0.065016577971470438, 0.067124653828023989, 0.069245144397250269, 0.071377949059141965,
- 0.073522973714240991, 0.075680130359194964, 0.077849336702372207, 0.080030515814947509,
- 0.082223595813495684, 0.084428509570654661, 0.086645194450867782, 0.088873592068594229,
- 0.091113648066700734, 0.093365311913026619, 0.095628536713353335, 0.097903279039215627,
- 0.100189498769172020, 0.102487158942306270, 0.104796225622867056, 0.107116667775072880,
- 0.109448457147210021, 0.111791568164245583, 0.114145977828255210, 0.116511665626037014,
- 0.118888613443345698, 0.121276805485235437, 0.123676228202051403, 0.126086870220650349,
- 0.128508722280473636, 0.130941777174128166, 0.133386029692162844, 0.135841476571757352,
- 0.138308116449064322, 0.140785949814968309, 0.143274978974047118, 0.145775208006537926,
- 0.148286642733128721, 0.150809290682410169, 0.153343161060837674, 0.155888264725064563,
- 0.158444614156520225, 0.161012223438117663, 0.163591108232982951, 0.166181285765110071,
- 0.168782774801850333, 0.171395595638155623, 0.174019770082499359, 0.176655321444406654,
- 0.179302274523530397, 0.181960655600216487, 0.184630492427504539, 0.187311814224516926,
- 0.190004651671193070, 0.192709036904328807, 0.195425003514885592, 0.198152586546538112,
- 0.200891822495431333, 0.203642749311121501, 0.206405406398679298, 0.209179834621935651,
- 0.211966076307852941, 0.214764175252008499, 0.217574176725178370, 0.220396127481011589,
- 0.223230075764789593, 0.226076071323264877, 0.228934165415577484, 0.231804410825248525,
- 0.234686861873252689, 0.237581574432173676, 0.240488605941449107, 0.243408015423711988,
- 0.246339863502238771, 0.249284212419516704, 0.252241126056943765, 0.255210669955677150,
- 0.258192911338648023, 0.261187919133763713, 0.264195763998317568, 0.267216518344631837,
- 0.270250256366959984, 0.273297054069675804, 0.276356989296781264, 0.279430141762765316,
- 0.282516593084849388, 0.285616426816658109, 0.288729728483353931, 0.291856585618280984,
- 0.294997087801162572, 0.298151326697901342, 0.301319396102034120, 0.304501391977896274,
- 0.307697412505553769, 0.310907558127563710, 0.314131931597630143, 0.317370638031222396,
- 0.320623784958230129, 0.323891482377732021, 0.327173842814958593, 0.330470981380537099,
- 0.333783015832108509, 0.337110066638412809, 0.340452257045945450, 0.343809713148291340,
- 0.347182563958251478, 0.350570941482881204, 0.353974980801569250, 0.357394820147290515,
- 0.360830600991175754, 0.364282468130549597, 0.367750569780596226, 0.371235057669821344,
- 0.374736087139491414, 0.378253817247238111, 0.381788410875031348, 0.385340034841733958,
- 0.388908860020464597, 0.392495061461010764, 0.396098818517547080, 0.399720314981931668,
- 0.403359739222868885, 0.407017284331247953, 0.410693148271983222, 0.414387534042706784,
- 0.418100649839684591, 0.421832709231353298, 0.425583931339900579, 0.429354541031341519,
- 0.433144769114574058, 0.436954852549929273, 0.440785034667769915, 0.444635565397727750,
- 0.448506701509214067, 0.452398706863882505, 0.456311852680773566, 0.460246417814923481,
- 0.464202689050278838, 0.468180961407822172, 0.472181538469883255, 0.476204732721683788,
- 0.480250865911249714, 0.484320269428911598, 0.488413284707712059, 0.492530263646148658,
- 0.496671569054796314, 0.500837575128482149, 0.505028667945828791, 0.509245245998136142,
- 0.513487720749743026, 0.517756517232200619, 0.522052074674794864, 0.526374847174186700,
- 0.530725304406193921, 0.535103932383019565, 0.539511234259544614, 0.543947731192649941,
- 0.548413963257921133, 0.552910490428519918, 0.557437893621486324, 0.561996775817277916,
- 0.566587763258951771, 0.571211506738074970, 0.575868682975210544, 0.580559996103683473,
- 0.585286179266300333, 0.590047996335791969, 0.594846243770991268, 0.599681752622167719,
- 0.604555390700549533, 0.609468064928895381, 0.614420723892076803, 0.619414360609039205,
- 0.624450015550274240, 0.629528779928128279, 0.634651799290960050, 0.639820277456438991,
- 0.645035480824251883, 0.650298743114294586, 0.655611470583224665, 0.660975147780241357,
- 0.666391343912380640, 0.671861719900766374, 0.677388036222513090, 0.682972161648791376,
- 0.688616083008527058, 0.694321916130032579, 0.700091918140490099, 0.705928501336797409,
- 0.711834248882358467, 0.717811932634901395, 0.723864533472881599, 0.729995264565802437,
- 0.736207598131266683, 0.742505296344636245, 0.748892447223726720, 0.755373506511754500,
- 0.761953346841546475, 0.768637315803334831, 0.775431304986138326, 0.782341832659861902,
- 0.789376143571198563, 0.796542330428254619, 0.803849483176389490, 0.811307874318219935,
- 0.818929191609414797, 0.826726833952094231, 0.834716292992930375, 0.842915653118441077,
- 0.851346258465123684, 0.860033621203008636, 0.869008688043793165, 0.878309655816146839,
- 0.887984660763399880, 0.898095921906304051, 0.908726440060562912, 0.919991505048360247,
- 0.932060075968990209, 0.945198953453078028, 0.959879091812415930, 0.977101701282731328,
- 1.000000000000000000];
-pub static ZIG_EXP_R: f64 = 7.697117470131050077;
-pub static ZIG_EXP_X: [f64, .. 257] =
- [8.697117470131052741, 7.697117470131050077, 6.941033629377212577, 6.478378493832569696,
- 6.144164665772472667, 5.882144315795399869, 5.666410167454033697, 5.482890627526062488,
- 5.323090505754398016, 5.181487281301500047, 5.054288489981304089, 4.938777085901250530,
- 4.832939741025112035, 4.735242996601741083, 4.644491885420085175, 4.559737061707351380,
- 4.480211746528421912, 4.405287693473573185, 4.334443680317273007, 4.267242480277365857,
- 4.203313713735184365, 4.142340865664051464, 4.084051310408297830, 4.028208544647936762,
- 3.974606066673788796, 3.923062500135489739, 3.873417670399509127, 3.825529418522336744,
- 3.779270992411667862, 3.734528894039797375, 3.691201090237418825, 3.649195515760853770,
- 3.608428813128909507, 3.568825265648337020, 3.530315889129343354, 3.492837654774059608,
- 3.456332821132760191, 3.420748357251119920, 3.386035442460300970, 3.352149030900109405,
- 3.319047470970748037, 3.286692171599068679, 3.255047308570449882, 3.224079565286264160,
- 3.193757903212240290, 3.164053358025972873, 3.134938858084440394, 3.106389062339824481,
- 3.078380215254090224, 3.050890016615455114, 3.023897504455676621, 2.997382949516130601,
- 2.971327759921089662, 2.945714394895045718, 2.920526286512740821, 2.895747768600141825,
- 2.871364012015536371, 2.847360965635188812, 2.823725302450035279, 2.800444370250737780,
- 2.777506146439756574, 2.754899196562344610, 2.732612636194700073, 2.710636095867928752,
- 2.688959688741803689, 2.667573980773266573, 2.646469963151809157, 2.625639026797788489,
- 2.605072938740835564, 2.584763820214140750, 2.564704126316905253, 2.544886627111869970,
- 2.525304390037828028, 2.505950763528594027, 2.486819361740209455, 2.467904050297364815,
- 2.449198932978249754, 2.430698339264419694, 2.412396812688870629, 2.394289099921457886,
- 2.376370140536140596, 2.358635057409337321, 2.341079147703034380, 2.323697874390196372,
- 2.306486858283579799, 2.289441870532269441, 2.272558825553154804, 2.255833774367219213,
- 2.239262898312909034, 2.222842503111036816, 2.206569013257663858, 2.190438966723220027,
- 2.174449009937774679, 2.158595893043885994, 2.142876465399842001, 2.127287671317368289,
- 2.111826546019042183, 2.096490211801715020, 2.081275874393225145, 2.066180819490575526,
- 2.051202409468584786, 2.036338080248769611, 2.021585338318926173, 2.006941757894518563,
- 1.992404978213576650, 1.977972700957360441, 1.963642687789548313, 1.949412758007184943,
- 1.935280786297051359, 1.921244700591528076, 1.907302480018387536, 1.893452152939308242,
- 1.879691795072211180, 1.866019527692827973, 1.852433515911175554, 1.838931967018879954,
- 1.825513128903519799, 1.812175288526390649, 1.798916770460290859, 1.785735935484126014,
- 1.772631179231305643, 1.759600930889074766, 1.746643651946074405, 1.733757834985571566,
- 1.720942002521935299, 1.708194705878057773, 1.695514524101537912, 1.682900062917553896,
- 1.670349953716452118, 1.657862852574172763, 1.645437439303723659, 1.633072416535991334,
- 1.620766508828257901, 1.608518461798858379, 1.596327041286483395, 1.584191032532688892,
- 1.572109239386229707, 1.560080483527888084, 1.548103603714513499, 1.536177455041032092,
- 1.524300908219226258, 1.512472848872117082, 1.500692176842816750, 1.488957805516746058,
- 1.477268661156133867, 1.465623682245745352, 1.454021818848793446, 1.442462031972012504,
- 1.430943292938879674, 1.419464582769983219, 1.408024891569535697, 1.396623217917042137,
- 1.385258568263121992, 1.373929956328490576, 1.362636402505086775, 1.351376933258335189,
- 1.340150580529504643, 1.328956381137116560, 1.317793376176324749, 1.306660610415174117,
- 1.295557131686601027, 1.284481990275012642, 1.273434238296241139, 1.262412929069615330,
- 1.251417116480852521, 1.240445854334406572, 1.229498195693849105, 1.218573192208790124,
- 1.207669893426761121, 1.196787346088403092, 1.185924593404202199, 1.175080674310911677,
- 1.164254622705678921, 1.153445466655774743, 1.142652227581672841, 1.131873919411078511,
- 1.121109547701330200, 1.110358108727411031, 1.099618588532597308, 1.088889961938546813,
- 1.078171191511372307, 1.067461226479967662, 1.056759001602551429, 1.046063435977044209,
- 1.035373431790528542, 1.024687873002617211, 1.014005623957096480, 1.003325527915696735,
- 0.992646405507275897, 0.981967053085062602, 0.971286240983903260, 0.960602711668666509,
- 0.949915177764075969, 0.939222319955262286, 0.928522784747210395, 0.917815182070044311,
- 0.907098082715690257, 0.896370015589889935, 0.885629464761751528, 0.874874866291025066,
- 0.864104604811004484, 0.853317009842373353, 0.842510351810368485, 0.831682837734273206,
- 0.820832606554411814, 0.809957724057418282, 0.799056177355487174, 0.788125868869492430,
- 0.777164609759129710, 0.766170112735434672, 0.755139984181982249, 0.744071715500508102,
- 0.732962673584365398, 0.721810090308756203, 0.710611050909655040, 0.699362481103231959,
- 0.688061132773747808, 0.676703568029522584, 0.665286141392677943, 0.653804979847664947,
- 0.642255960424536365, 0.630634684933490286, 0.618936451394876075, 0.607156221620300030,
- 0.595288584291502887, 0.583327712748769489, 0.571267316532588332, 0.559100585511540626,
- 0.546820125163310577, 0.534417881237165604, 0.521885051592135052, 0.509211982443654398,
- 0.496388045518671162, 0.483401491653461857, 0.470239275082169006, 0.456886840931420235,
- 0.443327866073552401, 0.429543940225410703, 0.415514169600356364, 0.401214678896277765,
- 0.386617977941119573, 0.371692145329917234, 0.356399760258393816, 0.340696481064849122,
- 0.324529117016909452, 0.307832954674932158, 0.290527955491230394, 0.272513185478464703,
- 0.253658363385912022, 0.233790483059674731, 0.212671510630966620, 0.189958689622431842,
- 0.165127622564187282, 0.137304980940012589, 0.104838507565818778, 0.063852163815001570,
- 0.000000000000000000];
-pub static ZIG_EXP_F: [f64, .. 257] =
- [0.000167066692307963, 0.000454134353841497, 0.000967269282327174, 0.001536299780301573,
- 0.002145967743718907, 0.002788798793574076, 0.003460264777836904, 0.004157295120833797,
- 0.004877655983542396, 0.005619642207205489, 0.006381905937319183, 0.007163353183634991,
- 0.007963077438017043, 0.008780314985808977, 0.009614413642502212, 0.010464810181029981,
- 0.011331013597834600, 0.012212592426255378, 0.013109164931254991, 0.014020391403181943,
- 0.014945968011691148, 0.015885621839973156, 0.016839106826039941, 0.017806200410911355,
- 0.018786700744696024, 0.019780424338009740, 0.020787204072578114, 0.021806887504283581,
- 0.022839335406385240, 0.023884420511558174, 0.024942026419731787, 0.026012046645134221,
- 0.027094383780955803, 0.028188948763978646, 0.029295660224637411, 0.030414443910466622,
- 0.031545232172893622, 0.032687963508959555, 0.033842582150874358, 0.035009037697397431,
- 0.036187284781931443, 0.037377282772959382, 0.038578995503074871, 0.039792391023374139,
- 0.041017441380414840, 0.042254122413316254, 0.043502413568888197, 0.044762297732943289,
- 0.046033761076175184, 0.047316792913181561, 0.048611385573379504, 0.049917534282706379,
- 0.051235237055126281, 0.052564494593071685, 0.053905310196046080, 0.055257689676697030,
- 0.056621641283742870, 0.057997175631200659, 0.059384305633420280, 0.060783046445479660,
- 0.062193415408541036, 0.063615431999807376, 0.065049117786753805, 0.066494496385339816,
- 0.067951593421936643, 0.069420436498728783, 0.070901055162371843, 0.072393480875708752,
- 0.073897746992364746, 0.075413888734058410, 0.076941943170480517, 0.078481949201606435,
- 0.080033947542319905, 0.081597980709237419, 0.083174093009632397, 0.084762330532368146,
- 0.086362741140756927, 0.087975374467270231, 0.089600281910032886, 0.091237516631040197,
- 0.092887133556043569, 0.094549189376055873, 0.096223742550432825, 0.097910853311492213,
- 0.099610583670637132, 0.101322997425953631, 0.103048160171257702, 0.104786139306570145,
- 0.106537004050001632, 0.108300825451033755, 0.110077676405185357, 0.111867631670056283,
- 0.113670767882744286, 0.115487163578633506, 0.117316899211555525, 0.119160057175327641,
- 0.121016721826674792, 0.122886979509545108, 0.124770918580830933, 0.126668629437510671,
- 0.128580204545228199, 0.130505738468330773, 0.132445327901387494, 0.134399071702213602,
- 0.136367070926428829, 0.138349428863580176, 0.140346251074862399, 0.142357645432472146,
- 0.144383722160634720, 0.146424593878344889, 0.148480375643866735, 0.150551185001039839,
- 0.152637142027442801, 0.154738369384468027, 0.156854992369365148, 0.158987138969314129,
- 0.161134939917591952, 0.163298528751901734, 0.165478041874935922, 0.167673618617250081,
- 0.169885401302527550, 0.172113535315319977, 0.174358169171353411, 0.176619454590494829,
- 0.178897546572478278, 0.181192603475496261, 0.183504787097767436, 0.185834262762197083,
- 0.188181199404254262, 0.190545769663195363, 0.192928149976771296, 0.195328520679563189,
- 0.197747066105098818, 0.200183974691911210, 0.202639439093708962, 0.205113656293837654,
- 0.207606827724221982, 0.210119159388988230, 0.212650861992978224, 0.215202151075378628,
- 0.217773247148700472, 0.220364375843359439, 0.222975768058120111, 0.225607660116683956,
- 0.228260293930716618, 0.230933917169627356, 0.233628783437433291, 0.236345152457059560,
- 0.239083290262449094, 0.241843469398877131, 0.244625969131892024, 0.247431075665327543,
- 0.250259082368862240, 0.253110290015629402, 0.255985007030415324, 0.258883549749016173,
- 0.261806242689362922, 0.264753418835062149, 0.267725419932044739, 0.270722596799059967,
- 0.273745309652802915, 0.276793928448517301, 0.279868833236972869, 0.282970414538780746,
- 0.286099073737076826, 0.289255223489677693, 0.292439288161892630, 0.295651704281261252,
- 0.298892921015581847, 0.302163400675693528, 0.305463619244590256, 0.308794066934560185,
- 0.312155248774179606, 0.315547685227128949, 0.318971912844957239, 0.322428484956089223,
- 0.325917972393556354, 0.329440964264136438, 0.332998068761809096, 0.336589914028677717,
- 0.340217149066780189, 0.343880444704502575, 0.347580494621637148, 0.351318016437483449,
- 0.355093752866787626, 0.358908472948750001, 0.362762973354817997, 0.366658079781514379,
- 0.370594648435146223, 0.374573567615902381, 0.378595759409581067, 0.382662181496010056,
- 0.386773829084137932, 0.390931736984797384, 0.395136981833290435, 0.399390684475231350,
- 0.403694012530530555, 0.408048183152032673, 0.412454465997161457, 0.416914186433003209,
- 0.421428728997616908, 0.425999541143034677, 0.430628137288459167, 0.435316103215636907,
- 0.440065100842354173, 0.444876873414548846, 0.449753251162755330, 0.454696157474615836,
- 0.459707615642138023, 0.464789756250426511, 0.469944825283960310, 0.475175193037377708,
- 0.480483363930454543, 0.485871987341885248, 0.491343869594032867, 0.496901987241549881,
- 0.502549501841348056, 0.508289776410643213, 0.514126393814748894, 0.520063177368233931,
- 0.526104213983620062, 0.532253880263043655, 0.538516872002862246, 0.544898237672440056,
- 0.551403416540641733, 0.558038282262587892, 0.564809192912400615, 0.571723048664826150,
- 0.578787358602845359, 0.586010318477268366, 0.593400901691733762, 0.600968966365232560,
- 0.608725382079622346, 0.616682180915207878, 0.624852738703666200, 0.633251994214366398,
- 0.641896716427266423, 0.650805833414571433, 0.660000841079000145, 0.669506316731925177,
- 0.679350572264765806, 0.689566496117078431, 0.700192655082788606, 0.711274760805076456,
- 0.722867659593572465, 0.735038092431424039, 0.747868621985195658, 0.761463388849896838,
- 0.775956852040116218, 0.791527636972496285, 0.808421651523009044, 0.826993296643051101,
- 0.847785500623990496, 0.871704332381204705, 0.900469929925747703, 0.938143680862176477,
- 1.000000000000000000];
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The ISAAC random number generator.
-
-use rand::{Rng, SeedableRng, OSRng};
-use iter::{Iterator, range, range_step, Repeat};
-use option::{None, Some};
-use vec::raw;
-use mem;
-
-static RAND_SIZE_LEN: u32 = 8;
-static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
-
-/// A random number generator that uses the ISAAC algorithm[1].
-///
-/// The ISAAC algorithm is generally accepted as suitable for
-/// cryptographic purposes, but this implementation has not be
-/// verified as such. Prefer a generator like `OSRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
-/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
-pub struct IsaacRng {
- priv cnt: u32,
- priv rsl: [u32, .. RAND_SIZE],
- priv mem: [u32, .. RAND_SIZE],
- priv a: u32,
- priv b: u32,
- priv c: u32
-}
-static EMPTY: IsaacRng = IsaacRng {
- cnt: 0,
- rsl: [0, .. RAND_SIZE],
- mem: [0, .. RAND_SIZE],
- a: 0, b: 0, c: 0
-};
-
-impl IsaacRng {
- /// Create an ISAAC random number generator with a random seed.
- pub fn new() -> IsaacRng {
- let mut rng = EMPTY;
-
- unsafe {
- let ptr = raw::to_mut_ptr(rng.rsl);
-
- raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
- OSRng::new().fill_bytes(slice);
- })
- }
-
- rng.init(true);
- rng
- }
-
- /// Create an ISAAC random number generator using the default
- /// fixed seed.
- pub fn new_unseeded() -> IsaacRng {
- let mut rng = EMPTY;
- rng.init(false);
- rng
- }
-
- /// Initialises `self`. If `use_rsl` is true, then use the current value
- /// of `rsl` as a seed, otherwise construct one algorithmically (not
- /// randomly).
- fn init(&mut self, use_rsl: bool) {
- let mut a = 0x9e3779b9;
- let mut b = a;
- let mut c = a;
- let mut d = a;
- let mut e = a;
- let mut f = a;
- let mut g = a;
- let mut h = a;
-
- macro_rules! mix(
- () => {{
- a^=b<<11; d+=a; b+=c;
- b^=c>>2; e+=b; c+=d;
- c^=d<<8; f+=c; d+=e;
- d^=e>>16; g+=d; e+=f;
- e^=f<<10; h+=e; f+=g;
- f^=g>>4; a+=f; g+=h;
- g^=h<<8; b+=g; h+=a;
- h^=a>>9; c+=h; a+=b;
- }}
- );
-
- 4.times(|| mix!());
-
- if use_rsl {
- macro_rules! memloop (
- ($arr:expr) => {{
- for i in range_step(0u32, RAND_SIZE, 8) {
- a+=$arr[i ]; b+=$arr[i+1];
- c+=$arr[i+2]; d+=$arr[i+3];
- e+=$arr[i+4]; f+=$arr[i+5];
- g+=$arr[i+6]; h+=$arr[i+7];
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }}
- );
-
- memloop!(self.rsl);
- memloop!(self.mem);
- } else {
- for i in range_step(0u32, RAND_SIZE, 8) {
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }
-
- self.isaac();
- }
-
- /// Refills the output buffer (`self.rsl`)
- #[inline]
- fn isaac(&mut self) {
- self.c += 1;
- // abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
-
- static MIDPOINT: uint = RAND_SIZE as uint / 2;
-
- macro_rules! ind (($x:expr) => {
- self.mem[($x >> 2) & (RAND_SIZE - 1)]
- });
- macro_rules! rngstep(
- ($j:expr, $shift:expr) => {{
- let base = $j;
- let mix = if $shift < 0 {
- a >> -$shift as uint
- } else {
- a << $shift as uint
- };
-
- let x = self.mem[base + mr_offset];
- a = (a ^ mix) + self.mem[base + m2_offset];
- let y = ind!(x) + a + b;
- self.mem[base + mr_offset] = y;
-
- b = ind!(y >> RAND_SIZE_LEN) + x;
- self.rsl[base + mr_offset] = b;
- }}
- );
-
- let r = [(0, MIDPOINT), (MIDPOINT, 0)];
- for &(mr_offset, m2_offset) in r.iter() {
- for i in range_step(0u, MIDPOINT, 4) {
- rngstep!(i + 0, 13);
- rngstep!(i + 1, -6);
- rngstep!(i + 2, 2);
- rngstep!(i + 3, -16);
- }
- }
-
- self.a = a;
- self.b = b;
- self.cnt = RAND_SIZE;
- }
-}
-
-impl Rng for IsaacRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- if self.cnt == 0 {
- // make some more numbers
- self.isaac();
- }
- self.cnt -= 1;
- self.rsl[self.cnt]
- }
-}
-
-impl<'self> SeedableRng<&'self [u32]> for IsaacRng {
- fn reseed(&mut self, seed: &'self [u32]) {
- // make the seed into [seed[0], seed[1], ..., seed[seed.len()
- // - 1], 0, 0, ...], to fill rng.rsl.
- let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u32));
-
- for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
- *rsl_elem = seed_elem;
- }
- self.cnt = 0;
- self.a = 0;
- self.b = 0;
- self.c = 0;
-
- self.init(true);
- }
-
- /// Create an ISAAC random number generator with a seed. This can
- /// be any length, although the maximum number of elements used is
- /// 256 and any more will be silently ignored. A generator
- /// constructed with a given seed will generate the same sequence
- /// of values as all other generators constructed with that seed.
- fn from_seed(seed: &'self [u32]) -> IsaacRng {
- let mut rng = EMPTY;
- rng.reseed(seed);
- rng
- }
-}
-
-
-static RAND_SIZE_64_LEN: uint = 8;
-static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
-
-/// A random number generator that uses ISAAC-64[1], the 64-bit
-/// variant of the ISAAC algorithm.
-///
-/// The ISAAC algorithm is generally accepted as suitable for
-/// cryptographic purposes, but this implementation has not be
-/// verified as such. Prefer a generator like `OSRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
-/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
-pub struct Isaac64Rng {
- priv cnt: uint,
- priv rsl: [u64, .. RAND_SIZE_64],
- priv mem: [u64, .. RAND_SIZE_64],
- priv a: u64,
- priv b: u64,
- priv c: u64,
-}
-
-static EMPTY_64: Isaac64Rng = Isaac64Rng {
- cnt: 0,
- rsl: [0, .. RAND_SIZE_64],
- mem: [0, .. RAND_SIZE_64],
- a: 0, b: 0, c: 0,
-};
-
-impl Isaac64Rng {
- /// Create a 64-bit ISAAC random number generator with a random
- /// seed.
- pub fn new() -> Isaac64Rng {
- let mut rng = EMPTY_64;
-
- unsafe {
- let ptr = raw::to_mut_ptr(rng.rsl);
-
- raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
- OSRng::new().fill_bytes(slice);
- })
- }
-
- rng.init(true);
- rng
- }
-
- /// Create a 64-bit ISAAC random number generator using the
- /// default fixed seed.
- pub fn new_unseeded() -> Isaac64Rng {
- let mut rng = EMPTY_64;
- rng.init(false);
- rng
- }
-
- /// Initialises `self`. If `use_rsl` is true, then use the current value
- /// of `rsl` as a seed, otherwise construct one algorithmically (not
- /// randomly).
- fn init(&mut self, use_rsl: bool) {
- macro_rules! init (
- ($var:ident) => (
- let mut $var = 0x9e3779b97f4a7c13;
- )
- );
- init!(a); init!(b); init!(c); init!(d);
- init!(e); init!(f); init!(g); init!(h);
-
- macro_rules! mix(
- () => {{
- a-=e; f^=h>>9; h+=a;
- b-=f; g^=a<<9; a+=b;
- c-=g; h^=b>>23; b+=c;
- d-=h; a^=c<<15; c+=d;
- e-=a; b^=d>>14; d+=e;
- f-=b; c^=e<<20; e+=f;
- g-=c; d^=f>>17; f+=g;
- h-=d; e^=g<<14; g+=h;
- }}
- );
-
- for _ in range(0, 4) { mix!(); }
- if use_rsl {
- macro_rules! memloop (
- ($arr:expr) => {{
- for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
- a+=$arr[i ]; b+=$arr[i+1];
- c+=$arr[i+2]; d+=$arr[i+3];
- e+=$arr[i+4]; f+=$arr[i+5];
- g+=$arr[i+6]; h+=$arr[i+7];
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }}
- );
-
- memloop!(self.rsl);
- memloop!(self.mem);
- } else {
- for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }
-
- self.isaac64();
- }
-
- /// Refills the output buffer (`self.rsl`)
- fn isaac64(&mut self) {
- self.c += 1;
- // abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
- static MIDPOINT: uint = RAND_SIZE_64 / 2;
- static MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
- macro_rules! ind (
- ($x:expr) => {
- self.mem.unsafe_get(($x as uint >> 3) & (RAND_SIZE_64 - 1))
- }
- );
- macro_rules! rngstep(
- ($j:expr, $shift:expr) => {{
- let base = base + $j;
- let mix = a ^ (if $shift < 0 {
- a >> -$shift as uint
- } else {
- a << $shift as uint
- });
- let mix = if $j == 0 {!mix} else {mix};
-
- unsafe {
- let x = self.mem.unsafe_get(base + mr_offset);
- a = mix + self.mem.unsafe_get(base + m2_offset);
- let y = ind!(x) + a + b;
- self.mem.unsafe_set(base + mr_offset, y);
-
- b = ind!(y >> RAND_SIZE_64_LEN) + x;
- self.rsl.unsafe_set(base + mr_offset, b);
- }
- }}
- );
-
- for &(mr_offset, m2_offset) in MP_VEC.iter() {
- for base in range(0, MIDPOINT / 4).map(|i| i * 4) {
- rngstep!(0, 21);
- rngstep!(1, -5);
- rngstep!(2, 12);
- rngstep!(3, -33);
- }
- }
-
- self.a = a;
- self.b = b;
- self.cnt = RAND_SIZE_64;
- }
-}
-
-impl Rng for Isaac64Rng {
- // FIXME #7771: having next_u32 like this should be unnecessary
- #[inline]
- fn next_u32(&mut self) -> u32 {
- self.next_u64() as u32
- }
-
- #[inline]
- fn next_u64(&mut self) -> u64 {
- if self.cnt == 0 {
- // make some more numbers
- self.isaac64();
- }
- self.cnt -= 1;
- unsafe { self.rsl.unsafe_get(self.cnt) }
- }
-}
-
-impl<'self> SeedableRng<&'self [u64]> for Isaac64Rng {
- fn reseed(&mut self, seed: &'self [u64]) {
- // make the seed into [seed[0], seed[1], ..., seed[seed.len()
- // - 1], 0, 0, ...], to fill rng.rsl.
- let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u64));
-
- for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
- *rsl_elem = seed_elem;
- }
- self.cnt = 0;
- self.a = 0;
- self.b = 0;
- self.c = 0;
-
- self.init(true);
- }
-
- /// Create an ISAAC random number generator with a seed. This can
- /// be any length, although the maximum number of elements used is
- /// 256 and any more will be silently ignored. A generator
- /// constructed with a given seed will generate the same sequence
- /// of values as all other generators constructed with that seed.
- fn from_seed(seed: &'self [u64]) -> Isaac64Rng {
- let mut rng = EMPTY_64;
- rng.reseed(seed);
- rng
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use rand::{Rng, SeedableRng, OSRng};
- use option::Some;
- use iter::range;
- use vec;
-
- #[test]
- fn test_rng_32_rand_seeded() {
- let s = OSRng::new().gen_vec::<u32>(256);
- let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
- let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice());
- assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
- }
- #[test]
- fn test_rng_64_rand_seeded() {
- let s = OSRng::new().gen_vec::<u64>(256);
- let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
- let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
- assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
- }
-
- #[test]
- fn test_rng_32_seeded() {
- let seed = &[1, 23, 456, 7890, 12345];
- let mut ra: IsaacRng = SeedableRng::from_seed(seed);
- let mut rb: IsaacRng = SeedableRng::from_seed(seed);
- assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
- }
- #[test]
- fn test_rng_64_seeded() {
- let seed = &[1, 23, 456, 7890, 12345];
- let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
- let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
- assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
- }
-
- #[test]
- fn test_rng_32_reseed() {
- let s = OSRng::new().gen_vec::<u32>(256);
- let mut r: IsaacRng = SeedableRng::from_seed(s.as_slice());
- let string1 = r.gen_ascii_str(100);
-
- r.reseed(s);
-
- let string2 = r.gen_ascii_str(100);
- assert_eq!(string1, string2);
- }
- #[test]
- fn test_rng_64_reseed() {
- let s = OSRng::new().gen_vec::<u64>(256);
- let mut r: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
- let string1 = r.gen_ascii_str(100);
-
- r.reseed(s);
-
- let string2 = r.gen_ascii_str(100);
- assert_eq!(string1, string2);
- }
-
- #[test]
- fn test_rng_32_true_values() {
- let seed = &[1, 23, 456, 7890, 12345];
- let mut ra: IsaacRng = SeedableRng::from_seed(seed);
- // Regression test that isaac is actually using the above vector
- let v = vec::from_fn(10, |_| ra.next_u32());
- assert_eq!(v,
- ~[2558573138, 873787463, 263499565, 2103644246, 3595684709,
- 4203127393, 264982119, 2765226902, 2737944514, 3900253796]);
-
- let seed = &[12345, 67890, 54321, 9876];
- let mut rb: IsaacRng = SeedableRng::from_seed(seed);
- // skip forward to the 10000th number
- for _ in range(0, 10000) { rb.next_u32(); }
-
- let v = vec::from_fn(10, |_| rb.next_u32());
- assert_eq!(v,
- ~[3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
- 1576568959, 3507990155, 179069555, 141456972, 2478885421]);
- }
- #[test]
- fn test_rng_64_true_values() {
- let seed = &[1, 23, 456, 7890, 12345];
- let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
- // Regression test that isaac is actually using the above vector
- let v = vec::from_fn(10, |_| ra.next_u64());
- assert_eq!(v,
- ~[547121783600835980, 14377643087320773276, 17351601304698403469,
- 1238879483818134882, 11952566807690396487, 13970131091560099343,
- 4469761996653280935, 15552757044682284409, 6860251611068737823,
- 13722198873481261842]);
-
- let seed = &[12345, 67890, 54321, 9876];
- let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
- // skip forward to the 10000th number
- for _ in range(0, 10000) { rb.next_u64(); }
-
- let v = vec::from_fn(10, |_| rb.next_u64());
- assert_eq!(v,
- ~[18143823860592706164, 8491801882678285927, 2699425367717515619,
- 17196852593171130876, 2606123525235546165, 15790932315217671084,
- 596345674630742204, 9947027391921273664, 11788097613744130851,
- 10391409374914919106]);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Random number generation.
-
-The key functions are `random()` and `Rng::gen()`. These are polymorphic
-and so can be used to generate any type that implements `Rand`. Type inference
-means that often a simple call to `rand::random()` or `rng.gen()` will
-suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`.
-
-See the `distributions` submodule for sampling random numbers from
-distributions like normal and exponential.
-
-# Task-local RNG
-
-There is built-in support for a RNG associated with each task stored
-in task-local storage. This RNG can be accessed via `task_rng`, or
-used implicitly via `random`. This RNG is normally randomly seeded
-from an operating-system source of randomness, e.g. `/dev/urandom` on
-Unix systems, and will automatically reseed itself from this source
-after generating 32 KiB of random data.
-
-# Cryptographic security
-
-An application that requires random numbers for cryptographic purposes
-should prefer `OSRng`, which reads randomness from one of the source
-that the operating system provides (e.g. `/dev/urandom` on
-Unixes). The other random number generators provided by this module
-are either known to be insecure (`XorShiftRng`), or are not verified
-to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
-
-*Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
-but it is a blocking RNG, and will wait until it has determined that
-it has collected enough entropy to fulfill a request for random
-data. It can be used with the `Rng` trait provided by this module by
-opening the file and passing it to `reader::ReaderRng`. Since it
-blocks, `/dev/random` should only be used to retrieve small amounts of
-randomness.
-
-# Examples
-
-```rust
-use std::rand;
-use std::rand::Rng;
-
-fn main() {
- let mut rng = rand::rng();
- if rng.gen() { // bool
- println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
- }
-}
- ```
-
-```rust
-use std::rand;
-
-fn main () {
- let tuple_ptr = rand::random::<~(f64, char)>();
- println!(tuple_ptr)
-}
- ```
-*/
-
-use cast;
-use cmp::Ord;
-use container::Container;
-use iter::{Iterator, range};
-use local_data;
-use prelude::*;
-use str;
-use vec;
-
-pub use self::isaac::{IsaacRng, Isaac64Rng};
-pub use self::os::OSRng;
-
-use self::distributions::{Range, IndependentSample};
-use self::distributions::range::SampleRange;
-
-pub mod distributions;
-pub mod isaac;
-pub mod os;
-pub mod reader;
-pub mod reseeding;
-mod rand_impls;
-
-/// A type that can be randomly generated using an Rng
-pub trait Rand {
- /// Generates a random instance of this type using the specified source of
- /// randomness
- fn rand<R: Rng>(rng: &mut R) -> Self;
-}
-
-/// A random number generator
-pub trait Rng {
- /// Return the next random u32. This rarely needs to be called
- /// directly, prefer `r.gen()` to `r.next_u32()`.
- ///
- // FIXME #7771: Should be implemented in terms of next_u64
- fn next_u32(&mut self) -> u32;
-
- /// Return the next random u64. This rarely needs to be called
- /// directly, prefer `r.gen()` to `r.next_u64()`.
- ///
- /// By default this is implemented in terms of `next_u32`. An
- /// implementation of this trait must provide at least one of
- /// these two methods.
- fn next_u64(&mut self) -> u64 {
- (self.next_u32() as u64 << 32) | (self.next_u32() as u64)
- }
-
- /// Fill `dest` with random data.
- ///
- /// This has a default implementation in terms of `next_u64` and
- /// `next_u32`, but should be overriden by implementations that
- /// offer a more efficient solution than just calling those
- /// methods repeatedly.
- ///
- /// This method does *not* have a requirement to bear any fixed
- /// relationship to the other methods, for example, it does *not*
- /// have to result in the same output as progressively filling
- /// `dest` with `self.gen::<u8>()`, and any such behaviour should
- /// not be relied upon.
- ///
- /// This method should guarantee that `dest` is entirely filled
- /// with new data, and may fail if this is impossible
- /// (e.g. reading past the end of a file that is being used as the
- /// source of randomness).
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand::{task_rng, Rng};
- ///
- /// fn main() {
- /// let mut v = [0u8, .. 13579];
- /// task_rng().fill_bytes(v);
- /// println!("{:?}", v);
- /// }
- /// ```
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- // this could, in theory, be done by transmuting dest to a
- // [u64], but this is (1) likely to be undefined behaviour for
- // LLVM, (2) has to be very careful about alignment concerns,
- // (3) adds more `unsafe` that needs to be checked, (4)
- // probably doesn't give much performance gain if
- // optimisations are on.
- let mut count = 0;
- let mut num = 0;
- for byte in dest.mut_iter() {
- if count == 0 {
- // we could micro-optimise here by generating a u32 if
- // we only need a few more bytes to fill the vector
- // (i.e. at most 4).
- num = self.next_u64();
- count = 8;
- }
-
- *byte = (num & 0xff) as u8;
- num >>= 8;
- count -= 1;
- }
- }
-
- /// Return a random value of a Rand type.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng = rand::task_rng();
- /// let x: uint = rng.gen();
- /// println!("{}", x);
- /// println!("{:?}", rng.gen::<(f64, bool)>());
- /// }
- /// ```
- #[inline(always)]
- fn gen<T: Rand>(&mut self) -> T {
- Rand::rand(self)
- }
-
- /// Return a random vector of the specified length.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng = rand::task_rng();
- /// let x: ~[uint] = rng.gen_vec(10);
- /// println!("{:?}", x);
- /// println!("{:?}", rng.gen_vec::<(f64, bool)>(5));
- /// }
- /// ```
- fn gen_vec<T: Rand>(&mut self, len: uint) -> ~[T] {
- vec::from_fn(len, |_| self.gen())
- }
-
- /// Generate a random value in the range [`low`, `high`). Fails if
- /// `low >= high`.
- ///
- /// This is a convenience wrapper around
- /// `distributions::Range`. If this function will be called
- /// repeatedly with the same arguments, one should use `Range`, as
- /// that will amortize the computations that allow for perfect
- /// uniformity, as they only happen on initialization.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng = rand::task_rng();
- /// let n: uint = rng.gen_range(0u, 10);
- /// println!("{}", n);
- /// let m: float = rng.gen_range(-40.0, 1.3e5);
- /// println!("{}", m);
- /// }
- /// ```
- fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
- assert!(low < high, "Rng.gen_range called with low >= high");
- Range::new(low, high).ind_sample(self)
- }
-
- /// Return a bool with a 1 in n chance of true
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng = rand::rng();
- /// println!("{:b}", rng.gen_weighted_bool(3));
- /// }
- /// ```
- fn gen_weighted_bool(&mut self, n: uint) -> bool {
- n == 0 || self.gen_range(0, n) == 0
- }
-
- /// Return a random string of the specified length composed of
- /// A-Z,a-z,0-9.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// println(rand::task_rng().gen_ascii_str(10));
- /// }
- /// ```
- fn gen_ascii_str(&mut self, len: uint) -> ~str {
- static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
- abcdefghijklmnopqrstuvwxyz\
- 0123456789");
- let mut s = str::with_capacity(len);
- for _ in range(0, len) {
- s.push_char(self.choose(GEN_ASCII_STR_CHARSET) as char)
- }
- s
- }
-
- /// Choose an item randomly, failing if `values` is empty.
- fn choose<T: Clone>(&mut self, values: &[T]) -> T {
- self.choose_option(values).expect("Rng.choose: `values` is empty").clone()
- }
-
- /// Choose `Some(&item)` randomly, returning `None` if values is
- /// empty.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// println!("{:?}", rand::task_rng().choose_option([1,2,4,8,16,32]));
- /// println!("{:?}", rand::task_rng().choose_option([]));
- /// }
- /// ```
- fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
- if values.is_empty() {
- None
- } else {
- Some(&values[self.gen_range(0u, values.len())])
- }
- }
-
- /// Shuffle a vec
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// println!("{:?}", rand::task_rng().shuffle(~[1,2,3]));
- /// }
- /// ```
- fn shuffle<T>(&mut self, values: ~[T]) -> ~[T] {
- let mut v = values;
- self.shuffle_mut(v);
- v
- }
-
- /// Shuffle a mutable vector in place.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng = rand::task_rng();
- /// let mut y = [1,2,3];
- /// rng.shuffle_mut(y);
- /// println!("{:?}", y);
- /// rng.shuffle_mut(y);
- /// println!("{:?}", y);
- /// }
- /// ```
- fn shuffle_mut<T>(&mut self, values: &mut [T]) {
- let mut i = values.len();
- while i >= 2u {
- // invariant: elements with index >= i have been locked in place.
- i -= 1u;
- // lock element i in place.
- values.swap(i, self.gen_range(0u, i + 1u));
- }
- }
-
- /// Randomly sample up to `n` elements from an iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng = rand::task_rng();
- /// let sample = rng.sample(range(1, 100), 5);
- /// println!("{:?}", sample);
- /// }
- /// ```
- fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
- let mut reservoir : ~[A] = vec::with_capacity(n);
- for (i, elem) in iter.enumerate() {
- if i < n {
- reservoir.push(elem);
- continue
- }
-
- let k = self.gen_range(0, i + 1);
- if k < reservoir.len() {
- reservoir[k] = elem
- }
- }
- reservoir
- }
-}
-
-/// A random number generator that can be explicitly seeded to produce
-/// the same stream of randomness multiple times.
-pub trait SeedableRng<Seed>: Rng {
- /// Reseed an RNG with the given seed.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng: rand::StdRng = rand::SeedableRng::from_seed(&[1, 2, 3, 4]);
- /// println!("{}", rng.gen::<f64>());
- /// rng.reseed([5, 6, 7, 8]);
- /// println!("{}", rng.gen::<f64>());
- /// }
- /// ```
- fn reseed(&mut self, Seed);
-
- /// Create a new RNG with the given seed.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::rand;
- /// use std::rand::Rng;
- ///
- /// fn main() {
- /// let mut rng: rand::StdRng = rand::SeedableRng::from_seed(&[1, 2, 3, 4]);
- /// println!("{}", rng.gen::<f64>());
- /// }
- /// ```
- fn from_seed(seed: Seed) -> Self;
-}
-
-/// Create a random number generator with a default algorithm and seed.
-///
-/// It returns the strongest `Rng` algorithm currently implemented in
-/// pure Rust. If you require a specifically seeded `Rng` for
-/// consistency over time you should pick one algorithm and create the
-/// `Rng` yourself.
-///
-/// This is a very expensive operation as it has to read randomness
-/// from the operating system and use this in an expensive seeding
-/// operation. If one does not require high performance generation of
-/// random numbers, `task_rng` and/or `random` may be more
-/// appropriate.
-pub fn rng() -> StdRng {
- StdRng::new()
-}
-
-/// The standard RNG. This is designed to be efficient on the current
-/// platform.
-#[cfg(not(target_word_size="64"))]
-pub struct StdRng { priv rng: IsaacRng }
-
-/// The standard RNG. This is designed to be efficient on the current
-/// platform.
-#[cfg(target_word_size="64")]
-pub struct StdRng { priv rng: Isaac64Rng }
-
-impl StdRng {
- /// Create a randomly seeded instance of `StdRng`. This reads
- /// randomness from the OS to seed the PRNG.
- #[cfg(not(target_word_size="64"))]
- pub fn new() -> StdRng {
- StdRng { rng: IsaacRng::new() }
- }
- /// Create a randomly seeded instance of `StdRng`. This reads
- /// randomness from the OS to seed the PRNG.
- #[cfg(target_word_size="64")]
- pub fn new() -> StdRng {
- StdRng { rng: Isaac64Rng::new() }
- }
-}
-
-impl Rng for StdRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- self.rng.next_u32()
- }
-
- #[inline]
- fn next_u64(&mut self) -> u64 {
- self.rng.next_u64()
- }
-}
-
-impl<'self> SeedableRng<&'self [uint]> for StdRng {
- fn reseed(&mut self, seed: &'self [uint]) {
- // the internal RNG can just be seeded from the above
- // randomness.
- self.rng.reseed(unsafe {cast::transmute(seed)})
- }
-
- fn from_seed(seed: &'self [uint]) -> StdRng {
- StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
- }
-}
-
-/// Create a weak random number generator with a default algorithm and seed.
-///
-/// It returns the fastest `Rng` algorithm currently available in Rust without
-/// consideration for cryptography or security. If you require a specifically
-/// seeded `Rng` for consistency over time you should pick one algorithm and
-/// create the `Rng` yourself.
-///
-/// This will read randomness from the operating system to seed the
-/// generator.
-pub fn weak_rng() -> XorShiftRng {
- XorShiftRng::new()
-}
-
-/// An Xorshift[1] random number
-/// generator.
-///
-/// The Xorshift algorithm is not suitable for cryptographic purposes
-/// but is very fast. If you do not know for sure that it fits your
-/// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
-///
-/// [1]: Marsaglia, George (July 2003). ["Xorshift
-/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
-/// Statistical Software*. Vol. 8 (Issue 14).
-pub struct XorShiftRng {
- priv x: u32,
- priv y: u32,
- priv z: u32,
- priv w: u32,
-}
-
-impl Rng for XorShiftRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- let x = self.x;
- let t = x ^ (x << 11);
- self.x = self.y;
- self.y = self.z;
- self.z = self.w;
- let w = self.w;
- self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
- self.w
- }
-}
-
-impl SeedableRng<[u32, .. 4]> for XorShiftRng {
- /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
- fn reseed(&mut self, seed: [u32, .. 4]) {
- assert!(!seed.iter().all(|&x| x == 0),
- "XorShiftRng.reseed called with an all zero seed.");
-
- self.x = seed[0];
- self.y = seed[1];
- self.z = seed[2];
- self.w = seed[3];
- }
-
- /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
- fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
- assert!(!seed.iter().all(|&x| x == 0),
- "XorShiftRng::from_seed called with an all zero seed.");
-
- XorShiftRng {
- x: seed[0],
- y: seed[1],
- z: seed[2],
- w: seed[3]
- }
- }
-}
-
-impl XorShiftRng {
- /// Create an xor shift random number generator with a random seed.
- pub fn new() -> XorShiftRng {
- let mut s = [0u8, ..16];
- loop {
- let mut r = OSRng::new();
- r.fill_bytes(s);
-
- if !s.iter().all(|x| *x == 0) {
- break;
- }
- }
- let s: [u32, ..4] = unsafe { cast::transmute(s) };
- SeedableRng::from_seed(s)
- }
-}
-
-/// Controls how the task-local RNG is reseeded.
-struct TaskRngReseeder;
-
-impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
- fn reseed(&mut self, rng: &mut StdRng) {
- *rng = StdRng::new();
- }
-}
-static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
-type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
-/// The task-local RNG.
-#[no_send]
-pub struct TaskRng {
- // This points into TLS (specifically, it points to the endpoint
- // of a ~ stored in TLS, to make it robust against TLS moving
- // things internally) and so this struct cannot be legally
- // transferred between tasks *and* it's unsafe to deallocate the
- // RNG other than when a task is finished.
- //
- // The use of unsafe code here is OK if the invariants above are
- // satisfied; and it allows us to avoid (unnecessarily) using a
- // GC'd or RC'd pointer.
- priv rng: *mut TaskRngInner
-}
-
-// used to make space in TLS for a random number generator
-local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
-
-/// Retrieve the lazily-initialized task-local random number
-/// generator, seeded by the system. Intended to be used in method
-/// chaining style, e.g. `task_rng().gen::<int>()`.
-///
-/// The RNG provided will reseed itself from the operating system
-/// after generating a certain amount of randomness.
-///
-/// The internal RNG used is platform and architecture dependent, even
-/// if the operating system random number generator is rigged to give
-/// the same sequence always. If absolute consistency is required,
-/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
-pub fn task_rng() -> TaskRng {
- local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
- None => {
- let mut rng = ~reseeding::ReseedingRng::new(StdRng::new(),
- TASK_RNG_RESEED_THRESHOLD,
- TaskRngReseeder);
- let ptr = &mut *rng as *mut TaskRngInner;
-
- local_data::set(TASK_RNG_KEY, rng);
-
- TaskRng { rng: ptr }
- }
- Some(rng) => TaskRng { rng: &mut **rng }
- })
-}
-
-impl Rng for TaskRng {
- fn next_u32(&mut self) -> u32 {
- unsafe { (*self.rng).next_u32() }
- }
-
- fn next_u64(&mut self) -> u64 {
- unsafe { (*self.rng).next_u64() }
- }
-
- #[inline]
- fn fill_bytes(&mut self, bytes: &mut [u8]) {
- unsafe { (*self.rng).fill_bytes(bytes) }
- }
-}
-
-/// Generate a random value using the task-local random number
-/// generator.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand::random;
-///
-/// fn main() {
-/// if random() {
-/// let x = random();
-/// println!("{}", 2u * x);
-/// } else {
-/// println!("{}", random::<f64>());
-/// }
-/// }
-/// ```
-#[inline]
-pub fn random<T: Rand>() -> T {
- task_rng().gen()
-}
-
-/// A wrapper for generating floating point numbers uniformly in the
-/// open interval `(0,1)` (not including either endpoint).
-///
-/// Use `Closed01` for the closed interval `[0,1]`, and the default
-/// `Rand` implementation for `f32` and `f64` for the half-open
-/// `[0,1)`.
-///
-/// # Example
-/// ```rust
-/// use std::rand::{random, Open01};
-///
-/// fn main() {
-/// println!("f32 from (0,1): {}", *random::<Open01<f32>>());
-///
-/// let x: Open01<f64> = random();
-/// println!("f64 from (0,1): {}", *x);
-/// }
-/// ```
-pub struct Open01<F>(F);
-
-/// A wrapper for generating floating point numbers uniformly in the
-/// closed interval `[0,1]` (including both endpoints).
-///
-/// Use `Open01` for the closed interval `(0,1)`, and the default
-/// `Rand` implementation of `f32` and `f64` for the half-open
-/// `[0,1)`.
-///
-/// # Example
-/// ```rust
-/// use std::rand::{random, Closed01};
-///
-/// fn main() {
-/// println!("f32 from [0,1]: {}", *random::<Closed01<f32>>());
-///
-/// let x: Closed01<f64> = random();
-/// println!("f64 from [0,1]: {}", *x);
-/// }
-/// ```
-pub struct Closed01<F>(F);
-
-#[cfg(test)]
-mod test {
- use iter::{Iterator, range};
- use option::{Option, Some};
- use vec;
- use super::*;
-
- struct ConstRng { i: u64 }
- impl Rng for ConstRng {
- fn next_u32(&mut self) -> u32 { self.i as u32 }
- fn next_u64(&mut self) -> u64 { self.i }
-
- // no fill_bytes on purpose
- }
-
- #[test]
- fn test_fill_bytes_default() {
- let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
-
- // check every remainder mod 8, both in small and big vectors.
- let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
- 80, 81, 82, 83, 84, 85, 86, 87];
- for &n in lengths.iter() {
- let mut v = vec::from_elem(n, 0u8);
- r.fill_bytes(v);
-
- // use this to get nicer error messages.
- for (i, &byte) in v.iter().enumerate() {
- if byte == 0 {
- fail!("byte {} of {} is zero", i, n)
- }
- }
- }
- }
-
- #[test]
- fn test_gen_range() {
- let mut r = rng();
- for _ in range(0, 1000) {
- let a = r.gen_range(-3i, 42);
- assert!(a >= -3 && a < 42);
- assert_eq!(r.gen_range(0, 1), 0);
- assert_eq!(r.gen_range(-12, -11), -12);
- }
-
- for _ in range(0, 1000) {
- let a = r.gen_range(10, 42);
- assert!(a >= 10 && a < 42);
- assert_eq!(r.gen_range(0, 1), 0);
- assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
- }
-
- }
-
- #[test]
- #[should_fail]
- fn test_gen_range_fail_int() {
- let mut r = rng();
- r.gen_range(5i, -2);
- }
-
- #[test]
- #[should_fail]
- fn test_gen_range_fail_uint() {
- let mut r = rng();
- r.gen_range(5u, 2u);
- }
-
- #[test]
- fn test_gen_f64() {
- let mut r = rng();
- let a = r.gen::<f64>();
- let b = r.gen::<f64>();
- debug!("{:?}", (a, b));
- }
-
- #[test]
- fn test_gen_weighted_bool() {
- let mut r = rng();
- assert_eq!(r.gen_weighted_bool(0u), true);
- assert_eq!(r.gen_weighted_bool(1u), true);
- }
-
- #[test]
- fn test_gen_ascii_str() {
- let mut r = rng();
- debug!("{}", r.gen_ascii_str(10u));
- debug!("{}", r.gen_ascii_str(10u));
- debug!("{}", r.gen_ascii_str(10u));
- assert_eq!(r.gen_ascii_str(0u).len(), 0u);
- assert_eq!(r.gen_ascii_str(10u).len(), 10u);
- assert_eq!(r.gen_ascii_str(16u).len(), 16u);
- }
-
- #[test]
- fn test_gen_vec() {
- let mut r = rng();
- assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
- assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
- assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
- }
-
- #[test]
- fn test_choose() {
- let mut r = rng();
- assert_eq!(r.choose([1, 1, 1]), 1);
- }
-
- #[test]
- fn test_choose_option() {
- let mut r = rng();
- let v: &[int] = &[];
- assert!(r.choose_option(v).is_none());
-
- let i = 1;
- let v = [1,1,1];
- assert_eq!(r.choose_option(v), Some(&i));
- }
-
- #[test]
- fn test_shuffle() {
- let mut r = rng();
- let empty: ~[int] = ~[];
- assert_eq!(r.shuffle(~[]), empty);
- assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
- }
-
- #[test]
- fn test_task_rng() {
- let mut r = task_rng();
- r.gen::<int>();
- assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
- assert_eq!(r.gen_range(0u, 1u), 0u);
- }
-
- #[test]
- fn test_random() {
- // not sure how to test this aside from just getting some values
- let _n : uint = random();
- let _f : f32 = random();
- let _o : Option<Option<i8>> = random();
- let _many : ((),
- (~uint, @int, ~Option<~(@u32, ~(@bool,))>),
- (u8, i8, u16, i16, u32, i32, u64, i64),
- (f32, (f64, (f64,)))) = random();
- }
-
- #[test]
- fn test_sample() {
- let MIN_VAL = 1;
- let MAX_VAL = 100;
-
- let mut r = rng();
- let vals = range(MIN_VAL, MAX_VAL).to_owned_vec();
- let small_sample = r.sample(vals.iter(), 5);
- let large_sample = r.sample(vals.iter(), vals.len() + 5);
-
- assert_eq!(small_sample.len(), 5);
- assert_eq!(large_sample.len(), vals.len());
-
- assert!(small_sample.iter().all(|e| {
- **e >= MIN_VAL && **e <= MAX_VAL
- }));
- }
-
- #[test]
- fn test_std_rng_seeded() {
- let s = OSRng::new().gen_vec::<uint>(256);
- let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
- let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
- assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
- }
-
- #[test]
- fn test_std_rng_reseed() {
- let s = OSRng::new().gen_vec::<uint>(256);
- let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
- let string1 = r.gen_ascii_str(100);
-
- r.reseed(s);
-
- let string2 = r.gen_ascii_str(100);
- assert_eq!(string1, string2);
- }
-}
-
-static RAND_BENCH_N: u64 = 100;
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
- use rand::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
- use mem::size_of;
- use iter::range;
- use option::{Some, None};
-
- #[bench]
- fn rand_xorshift(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new();
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- rng.gen::<uint>();
- }
- });
- bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
- }
-
- #[bench]
- fn rand_isaac(bh: &mut BenchHarness) {
- let mut rng = IsaacRng::new();
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- rng.gen::<uint>();
- }
- });
- bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
- }
-
- #[bench]
- fn rand_isaac64(bh: &mut BenchHarness) {
- let mut rng = Isaac64Rng::new();
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- rng.gen::<uint>();
- }
- });
- bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
- }
-
- #[bench]
- fn rand_std(bh: &mut BenchHarness) {
- let mut rng = StdRng::new();
- bh.iter(|| {
- for _ in range(0, RAND_BENCH_N) {
- rng.gen::<uint>();
- }
- });
- bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
- }
-
- #[bench]
- fn rand_shuffle_100(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new();
- let x : &mut[uint] = [1,..100];
- bh.iter(|| {
- rng.shuffle_mut(x);
- })
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Interfaces to the operating system provided random number
-//! generators.
-
-use rand::Rng;
-use ops::Drop;
-
-#[cfg(unix)]
-use rand::reader::ReaderRng;
-#[cfg(unix)]
-use io::File;
-
-#[cfg(windows)]
-use cast;
-#[cfg(windows)]
-use libc::{c_long, DWORD, BYTE};
-#[cfg(windows)]
-type HCRYPTPROV = c_long;
-// the extern functions imported from the runtime on Windows are
-// implemented so that they either succeed or abort(), so we can just
-// assume they work when we call them.
-
-/// A random number generator that retrieves randomness straight from
-/// the operating system. Platform sources:
-///
-/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
-/// `/dev/urandom`.
-/// - Windows: calls `CryptGenRandom`, using the default cryptographic
-/// service provider with the `PROV_RSA_FULL` type.
-///
-/// This does not block.
-#[cfg(unix)]
-pub struct OSRng {
- priv inner: ReaderRng<File>
-}
-/// A random number generator that retrieves randomness straight from
-/// the operating system. Platform sources:
-///
-/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
-/// `/dev/urandom`.
-/// - Windows: calls `CryptGenRandom`, using the default cryptographic
-/// service provider with the `PROV_RSA_FULL` type.
-///
-/// This does not block.
-#[cfg(windows)]
-pub struct OSRng {
- priv hcryptprov: HCRYPTPROV
-}
-
-impl OSRng {
- /// Create a new `OSRng`.
- #[cfg(unix)]
- pub fn new() -> OSRng {
- use path::Path;
- let reader = File::open(&Path::new("/dev/urandom"));
- let reader = reader.expect("Error opening /dev/urandom");
- let reader_rng = ReaderRng::new(reader);
-
- OSRng { inner: reader_rng }
- }
-
- /// Create a new `OSRng`.
- #[cfg(windows)]
- pub fn new() -> OSRng {
- extern { fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV); }
-
- let mut hcp = 0;
- unsafe {rust_win32_rand_acquire(&mut hcp)};
-
- OSRng { hcryptprov: hcp }
- }
-}
-
-#[cfg(unix)]
-impl Rng for OSRng {
- fn next_u32(&mut self) -> u32 {
- self.inner.next_u32()
- }
- fn next_u64(&mut self) -> u64 {
- self.inner.next_u64()
- }
- fn fill_bytes(&mut self, v: &mut [u8]) {
- self.inner.fill_bytes(v)
- }
-}
-
-#[cfg(windows)]
-impl Rng for OSRng {
- fn next_u32(&mut self) -> u32 {
- let mut v = [0u8, .. 4];
- self.fill_bytes(v);
- unsafe { cast::transmute(v) }
- }
- fn next_u64(&mut self) -> u64 {
- let mut v = [0u8, .. 8];
- self.fill_bytes(v);
- unsafe { cast::transmute(v) }
- }
- fn fill_bytes(&mut self, v: &mut [u8]) {
- extern {
- fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD,
- pbBuffer: *mut BYTE);
- }
-
- v.as_mut_buf(|ptr, len| {
- unsafe {rust_win32_rand_gen(self.hcryptprov, len as DWORD, ptr)}
- })
- }
-}
-
-impl Drop for OSRng {
- #[cfg(unix)]
- fn drop(&mut self) {
- // ensure that OSRng is not implicitly copyable on all
- // platforms, for consistency.
- }
-
- #[cfg(windows)]
- fn drop(&mut self) {
- extern { fn rust_win32_rand_release(hProv: HCRYPTPROV); }
-
- unsafe {rust_win32_rand_release(self.hcryptprov)}
- }
-}
-
-
-#[cfg(test)]
-mod test {
- use super::*;
- use rand::Rng;
-
- #[test]
- fn test_os_rng() {
- let mut r = OSRng::new();
-
- r.next_u32();
- r.next_u64();
-
- let mut v = [0u8, .. 1000];
- r.fill_bytes(v);
- }
-
- #[test]
- fn test_os_rng_tasks() {
- use task;
- use comm;
- use comm::{GenericChan, GenericPort};
- use option::{None, Some};
- use iter::{Iterator, range};
- use vec::{ImmutableVector, OwnedVector};
-
- let mut chans = ~[];
- for _ in range(0, 20) {
- let (p, c) = comm::stream();
- chans.push(c);
- do task::spawn {
- // wait until all the tasks are ready to go.
- p.recv();
-
- // deschedule to attempt to interleave things as much
- // as possible (XXX: is this a good test?)
- let mut r = OSRng::new();
- task::deschedule();
- let mut v = [0u8, .. 1000];
-
- for _ in range(0, 100) {
- r.next_u32();
- task::deschedule();
- r.next_u64();
- task::deschedule();
- r.fill_bytes(v);
- task::deschedule();
- }
- }
- }
-
- // start all the tasks
- for c in chans.iter() {
- c.send(())
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The implementations of `Rand` for the built-in types.
-
-use char;
-use int;
-use option::{Option, Some, None};
-use rand::{Rand,Rng};
-use uint;
-
-impl Rand for int {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> int {
- if int::bits == 32 {
- rng.gen::<i32>() as int
- } else {
- rng.gen::<i64>() as int
- }
- }
-}
-
-impl Rand for i8 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> i8 {
- rng.next_u32() as i8
- }
-}
-
-impl Rand for i16 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> i16 {
- rng.next_u32() as i16
- }
-}
-
-impl Rand for i32 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> i32 {
- rng.next_u32() as i32
- }
-}
-
-impl Rand for i64 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> i64 {
- rng.next_u64() as i64
- }
-}
-
-impl Rand for uint {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> uint {
- if uint::bits == 32 {
- rng.gen::<u32>() as uint
- } else {
- rng.gen::<u64>() as uint
- }
- }
-}
-
-impl Rand for u8 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> u8 {
- rng.next_u32() as u8
- }
-}
-
-impl Rand for u16 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> u16 {
- rng.next_u32() as u16
- }
-}
-
-impl Rand for u32 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> u32 {
- rng.next_u32()
- }
-}
-
-impl Rand for u64 {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> u64 {
- rng.next_u64()
- }
-}
-
-macro_rules! float_impls {
- ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident, $ignored_bits:expr) => {
- mod $mod_name {
- use rand::{Rand, Rng, Open01, Closed01};
-
- static SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
-
- impl Rand for $ty {
- /// Generate a floating point number in the half-open
- /// interval `[0,1)`.
- ///
- /// See `Closed01` for the closed interval `[0,1]`,
- /// and `Open01` for the open interval `(0,1)`.
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> $ty {
- // using any more than `mantissa_bits` bits will
- // cause (e.g.) 0xffff_ffff to correspond to 1
- // exactly, so we need to drop some (8 for f32, 11
- // for f64) to guarantee the open end.
- (rng.$method_name() >> $ignored_bits) as $ty / SCALE
- }
- }
- impl Rand for Open01<$ty> {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
- // add a small amount (specifically 2 bits below
- // the precision of f64/f32 at 1.0), so that small
- // numbers are larger than 0, but large numbers
- // aren't pushed to/above 1.
- Open01(((rng.$method_name() >> $ignored_bits) as $ty + 0.25) / SCALE)
- }
- }
- impl Rand for Closed01<$ty> {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
- // divide by the maximum value of the numerator to
- // get a non-zero probability of getting exactly
- // 1.0.
- Closed01((rng.$method_name() >> $ignored_bits) as $ty / (SCALE - 1.0))
- }
- }
- }
- }
-}
-float_impls! { f64_rand_impls, f64, 53, next_u64, 11 }
-float_impls! { f32_rand_impls, f32, 24, next_u32, 8 }
-
-impl Rand for char {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> char {
- // a char is 21 bits
- static CHAR_MASK: u32 = 0x001f_ffff;
- loop {
- // Rejection sampling. About 0.2% of numbers with at most
- // 21-bits are invalid codepoints (surrogates), so this
- // will succeed first go almost every time.
- match char::from_u32(rng.next_u32() & CHAR_MASK) {
- Some(c) => return c,
- None => {}
- }
- }
- }
-}
-
-impl Rand for bool {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> bool {
- rng.gen::<u8>() & 1 == 1
- }
-}
-
-macro_rules! tuple_impl {
- // use variables to indicate the arity of the tuple
- ($($tyvar:ident),* ) => {
- // the trailing commas are for the 1 tuple
- impl<
- $( $tyvar : Rand ),*
- > Rand for ( $( $tyvar ),* , ) {
-
- #[inline]
- fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
- (
- // use the $tyvar's to get the appropriate number of
- // repeats (they're not actually needed)
- $(
- _rng.gen::<$tyvar>()
- ),*
- ,
- )
- }
- }
- }
-}
-
-impl Rand for () {
- #[inline]
- fn rand<R: Rng>(_: &mut R) -> () { () }
-}
-tuple_impl!{A}
-tuple_impl!{A, B}
-tuple_impl!{A, B, C}
-tuple_impl!{A, B, C, D}
-tuple_impl!{A, B, C, D, E}
-tuple_impl!{A, B, C, D, E, F}
-tuple_impl!{A, B, C, D, E, F, G}
-tuple_impl!{A, B, C, D, E, F, G, H}
-tuple_impl!{A, B, C, D, E, F, G, H, I}
-tuple_impl!{A, B, C, D, E, F, G, H, I, J}
-
-impl<T:Rand> Rand for Option<T> {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> Option<T> {
- if rng.gen() {
- Some(rng.gen())
- } else {
- None
- }
- }
-}
-
-impl<T: Rand> Rand for ~T {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
-}
-
-impl<T: Rand + 'static> Rand for @T {
- #[inline]
- fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
-}
-
-#[cfg(test)]
-mod tests {
- use rand::{Rng, task_rng, Open01, Closed01};
- use iter::range;
- use option::{None, Some};
-
- struct ConstantRng(u64);
- impl Rng for ConstantRng {
- fn next_u32(&mut self) -> u32 {
- (**self) as u32
- }
- fn next_u64(&mut self) -> u64 {
- **self
- }
- }
-
- fn floating_point_edge_cases() {
- // the test for exact equality is correct here.
- assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0)
- assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0)
- }
-
- fn rand_open() {
- // this is unlikely to catch an incorrect implementation that
- // generates exactly 0 or 1, but it keeps it sane.
- let mut rng = task_rng();
- for _ in range(0, 1_000) {
- // strict inequalities
- let f = *rng.gen::<Open01<f64>>();
- assert!(0.0 < f && f < 1.0);
-
- let f = *rng.gen::<Open01<f32>>();
- assert!(0.0 < f && f < 1.0);
- }
- }
-
- fn rand_closed() {
- let mut rng = task_rng();
- for _ in range(0, 1_000) {
- // strict inequalities
- let f = *rng.gen::<Closed01<f64>>();
- assert!(0.0 <= f && f <= 1.0);
-
- let f = *rng.gen::<Closed01<f32>>();
- assert!(0.0 <= f && f <= 1.0);
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A wrapper around any Reader to treat it as an RNG.
-
-use option::{Some, None};
-use io::Reader;
-
-use rand::Rng;
-
-/// An RNG that reads random bytes straight from a `Reader`. This will
-/// work best with an infinite reader, but this is not required.
-///
-/// It will fail if it there is insufficient data to fulfill a request.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand::{reader, Rng};
-/// use std::io::mem;
-///
-/// fn main() {
-/// let mut rng = reader::ReaderRng::new(mem::MemReader::new(~[1,2,3,4,5,6,7,8]));
-/// println!("{:x}", rng.gen::<uint>());
-/// }
-/// ```
-pub struct ReaderRng<R> {
- priv reader: R
-}
-
-impl<R: Reader> ReaderRng<R> {
- /// Create a new `ReaderRng` from a `Reader`.
- pub fn new(r: R) -> ReaderRng<R> {
- ReaderRng {
- reader: r
- }
- }
-}
-
-impl<R: Reader> Rng for ReaderRng<R> {
- fn next_u32(&mut self) -> u32 {
- // This is designed for speed: reading a LE integer on a LE
- // platform just involves blitting the bytes into the memory
- // of the u32, similarly for BE on BE; avoiding byteswapping.
- if cfg!(target_endian="little") {
- self.reader.read_le_u32()
- } else {
- self.reader.read_be_u32()
- }
- }
- fn next_u64(&mut self) -> u64 {
- // see above for explanation.
- if cfg!(target_endian="little") {
- self.reader.read_le_u64()
- } else {
- self.reader.read_be_u64()
- }
- }
- fn fill_bytes(&mut self, v: &mut [u8]) {
- if v.len() == 0 { return }
- match self.reader.read(v) {
- Some(n) if n == v.len() => return,
- Some(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
- read {} out of {} bytes.", n, v.len()),
- None => fail!("ReaderRng.fill_bytes reached eof.")
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use io::mem::MemReader;
- use cast;
-
- #[test]
- fn test_reader_rng_u64() {
- // transmute from the target to avoid endianness concerns.
- let v = ~[1u64, 2u64, 3u64];
- let bytes: ~[u8] = unsafe {cast::transmute(v)};
- let mut rng = ReaderRng::new(MemReader::new(bytes));
-
- assert_eq!(rng.next_u64(), 1);
- assert_eq!(rng.next_u64(), 2);
- assert_eq!(rng.next_u64(), 3);
- }
- #[test]
- fn test_reader_rng_u32() {
- // transmute from the target to avoid endianness concerns.
- let v = ~[1u32, 2u32, 3u32];
- let bytes: ~[u8] = unsafe {cast::transmute(v)};
- let mut rng = ReaderRng::new(MemReader::new(bytes));
-
- assert_eq!(rng.next_u32(), 1);
- assert_eq!(rng.next_u32(), 2);
- assert_eq!(rng.next_u32(), 3);
- }
- #[test]
- fn test_reader_rng_fill_bytes() {
- let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let mut w = [0u8, .. 8];
-
- let mut rng = ReaderRng::new(MemReader::new(v.to_owned()));
- rng.fill_bytes(w);
-
- assert_eq!(v, w);
- }
-
- #[test]
- #[should_fail]
- fn test_reader_rng_insufficient_bytes() {
- let mut rng = ReaderRng::new(MemReader::new(~[]));
- let mut v = [0u8, .. 3];
- rng.fill_bytes(v);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A wrapper around another RNG that reseeds it after it
-//! generates a certain number of random bytes.
-
-use rand::{Rng, SeedableRng};
-use default::Default;
-
-/// How many bytes of entropy the underling RNG is allowed to generate
-/// before it is reseeded.
-static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
-
-/// A wrapper around any RNG which reseeds the underlying RNG after it
-/// has generated a certain number of random bytes.
-pub struct ReseedingRng<R, Rsdr> {
- priv rng: R,
- priv generation_threshold: uint,
- priv bytes_generated: uint,
- /// Controls the behaviour when reseeding the RNG.
- reseeder: Rsdr
-}
-
-impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
- /// Create a new `ReseedingRng` with the given parameters.
- ///
- /// # Arguments
- ///
- /// * `rng`: the random number generator to use.
- /// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG.
- /// * `reseeder`: the reseeding object to use.
- pub fn new(rng: R, generation_threshold: uint, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
- ReseedingRng {
- rng: rng,
- generation_threshold: generation_threshold,
- bytes_generated: 0,
- reseeder: reseeder
- }
- }
-
- /// Reseed the internal RNG if the number of bytes that have been
- /// generated exceed the threshold.
- pub fn reseed_if_necessary(&mut self) {
- if self.bytes_generated >= self.generation_threshold {
- self.reseeder.reseed(&mut self.rng);
- self.bytes_generated = 0;
- }
- }
-}
-
-
-impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
- fn next_u32(&mut self) -> u32 {
- self.reseed_if_necessary();
- self.bytes_generated += 4;
- self.rng.next_u32()
- }
-
- fn next_u64(&mut self) -> u64 {
- self.reseed_if_necessary();
- self.bytes_generated += 8;
- self.rng.next_u64()
- }
-
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- self.reseed_if_necessary();
- self.bytes_generated += dest.len();
- self.rng.fill_bytes(dest)
- }
-}
-
-impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>>
- SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> {
- fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) {
- self.rng.reseed(seed);
- self.reseeder = rsdr;
- self.bytes_generated = 0;
- }
- /// Create a new `ReseedingRng` from the given reseeder and
- /// seed. This uses a default value for `generation_threshold`.
- fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> {
- ReseedingRng {
- rng: SeedableRng::from_seed(seed),
- generation_threshold: DEFAULT_GENERATION_THRESHOLD,
- bytes_generated: 0,
- reseeder: rsdr
- }
- }
-}
-
-/// Something that can be used to reseed an RNG via `ReseedingRng`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::{Rng, SeedableRng};
-/// use std::rand::reseeding::{Reseeder, ReseedingRng};
-///
-/// struct TickTockReseeder { tick: bool }
-/// impl Reseeder<rand::StdRng> for TickTockReseeder {
-/// fn reseed(&mut self, rng: &mut rand::StdRng) {
-/// let val = if self.tick {0} else {1};
-/// rng.reseed(&[val]);
-/// self.tick = !self.tick;
-/// }
-/// }
-/// fn main() {
-/// let rsdr = TickTockReseeder { tick: true };
-/// let mut rng = ReseedingRng::new(rand::StdRng::new(), 10, rsdr);
-///
-/// // this will repeat, because it gets reseeded very regularly.
-/// println(rng.gen_ascii_str(100));
-/// }
-///
-/// ```
-pub trait Reseeder<R> {
- /// Reseed the given RNG.
- fn reseed(&mut self, rng: &mut R);
-}
-
-/// Reseed an RNG using a `Default` instance. This reseeds by
-/// replacing the RNG with the result of a `Default::default` call.
-pub struct ReseedWithDefault;
-
-impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
- fn reseed(&mut self, rng: &mut R) {
- *rng = Default::default();
- }
-}
-impl Default for ReseedWithDefault {
- fn default() -> ReseedWithDefault { ReseedWithDefault }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use rand::{SeedableRng, Rng};
- use default::Default;
- use iter::range;
- use option::{None, Some};
-
- struct Counter {
- i: u32
- }
-
- impl Rng for Counter {
- fn next_u32(&mut self) -> u32 {
- self.i += 1;
- // very random
- self.i - 1
- }
- }
- impl Default for Counter {
- fn default() -> Counter {
- Counter { i: 0 }
- }
- }
- impl SeedableRng<u32> for Counter {
- fn reseed(&mut self, seed: u32) {
- self.i = seed;
- }
- fn from_seed(seed: u32) -> Counter {
- Counter { i: seed }
- }
- }
- type MyRng = ReseedingRng<Counter, ReseedWithDefault>;
-
- #[test]
- fn test_reseeding() {
- let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
-
- let mut i = 0;
- for _ in range(0, 1000) {
- assert_eq!(rs.next_u32(), i % 100);
- i += 1;
- }
- }
-
- #[test]
- fn test_rng_seeded() {
- let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
- let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
- assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
- }
-
- #[test]
- fn test_rng_reseed() {
- let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3));
- let string1 = r.gen_ascii_str(100);
-
- r.reseed((ReseedWithDefault, 3));
-
- let string2 = r.gen_ascii_str(100);
- assert_eq!(string1, string2);
- }
-
- static fill_bytes_v_len: uint = 13579;
- #[test]
- fn test_rng_fill_bytes() {
- use rand::task_rng;
- let mut v = ~[0u8, .. fill_bytes_v_len];
- task_rng().fill_bytes(v);
-
- // Sanity test: if we've gotten here, `fill_bytes` has not infinitely
- // recursed.
- assert_eq!(v.len(), fill_bytes_v_len);
-
- // To test that `fill_bytes` actually did something, check that the
- // average of `v` is not 0.
- let mut sum = 0.0;
- for &x in v.iter() {
- sum += x as f64;
- }
- assert!(sum / v.len() as f64 != 0.0);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! Task-local reference counted boxes
-
-The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
-will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
-overhead of atomic reference counting.
-
-*/
-
-use ptr::RawPtr;
-use unstable::intrinsics::transmute;
-use ops::Drop;
-use kinds::{Freeze, Send};
-use clone::{Clone, DeepClone};
-use cell::RefCell;
-use cmp::{Eq, TotalEq, Ord, TotalOrd, Ordering};
-
-struct RcBox<T> {
- value: T,
- count: uint
-}
-
-/// Immutable reference counted pointer type
-#[unsafe_no_drop_flag]
-#[no_send]
-pub struct Rc<T> {
- priv ptr: *mut RcBox<T>
-}
-
-impl<T: Freeze> Rc<T> {
- /// Construct a new reference-counted box from a `Freeze` value
- #[inline]
- pub fn new(value: T) -> Rc<T> {
- unsafe {
- Rc::new_unchecked(value)
- }
- }
-}
-
-impl<T: Send> Rc<T> {
- /// Construct a new reference-counted box from a `Send` value
- #[inline]
- pub fn from_send(value: T) -> Rc<T> {
- unsafe {
- Rc::new_unchecked(value)
- }
- }
-}
-
-impl<T: Freeze> Rc<RefCell<T>> {
- /// Construct a new reference-counted box from a `RefCell`-wrapped `Freeze` value
- #[inline]
- pub fn from_mut(value: RefCell<T>) -> Rc<RefCell<T>> {
- unsafe {
- Rc::new_unchecked(value)
- }
- }
-}
-
-impl<T> Rc<T> {
- /// Unsafety construct a new reference-counted box from any value.
- ///
- /// It is possible to create cycles, which will leak, and may interact
- /// poorly with managed pointers.
- #[inline]
- pub unsafe fn new_unchecked(value: T) -> Rc<T> {
- Rc{ptr: transmute(~RcBox{value: value, count: 1})}
- }
-
- /// Borrow the value contained in the reference-counted box
- #[inline]
- pub fn borrow<'r>(&'r self) -> &'r T {
- unsafe { &(*self.ptr).value }
- }
-
- /// Determine if two reference-counted pointers point to the same object
- #[inline]
- pub fn ptr_eq(&self, other: &Rc<T>) -> bool {
- self.ptr == other.ptr
- }
-}
-
-impl<T: Eq> Eq for Rc<T> {
- #[inline]
- fn eq(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value == (*other.ptr).value }
- }
-
- #[inline]
- fn ne(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value != (*other.ptr).value }
- }
-}
-
-impl<T: TotalEq> TotalEq for Rc<T> {
- #[inline]
- fn equals(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value.equals(&(*other.ptr).value) }
- }
-}
-
-impl<T: Ord> Ord for Rc<T> {
- #[inline]
- fn lt(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value < (*other.ptr).value }
- }
-
- #[inline]
- fn le(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value <= (*other.ptr).value }
- }
-
- #[inline]
- fn ge(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value >= (*other.ptr).value }
- }
-
- #[inline]
- fn gt(&self, other: &Rc<T>) -> bool {
- unsafe { (*self.ptr).value > (*other.ptr).value }
- }
-}
-
-impl<T: TotalOrd> TotalOrd for Rc<T> {
- #[inline]
- fn cmp(&self, other: &Rc<T>) -> Ordering {
- unsafe { (*self.ptr).value.cmp(&(*other.ptr).value) }
- }
-}
-
-impl<T> Clone for Rc<T> {
- #[inline]
- fn clone(&self) -> Rc<T> {
- unsafe {
- (*self.ptr).count += 1;
- Rc{ptr: self.ptr}
- }
- }
-}
-
-impl<T: DeepClone> DeepClone for Rc<T> {
- #[inline]
- fn deep_clone(&self) -> Rc<T> {
- unsafe { Rc::new_unchecked(self.borrow().deep_clone()) }
- }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for Rc<T> {
- fn drop(&mut self) {
- unsafe {
- if self.ptr.is_not_null() {
- (*self.ptr).count -= 1;
- if (*self.ptr).count == 0 {
- let _: ~RcBox<T> = transmute(self.ptr);
- }
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test_rc {
- use super::*;
- use cell::RefCell;
-
- #[test]
- fn test_clone() {
- let x = Rc::from_send(RefCell::new(5));
- let y = x.clone();
- x.borrow().with_mut(|inner| {
- *inner = 20;
- });
- assert_eq!(y.borrow().with(|v| *v), 20);
- }
-
- #[test]
- fn test_deep_clone() {
- let x = Rc::from_send(RefCell::new(5));
- let y = x.deep_clone();
- x.borrow().with_mut(|inner| {
- *inner = 20;
- });
- assert_eq!(y.borrow().with(|v| *v), 5);
- }
-
- #[test]
- fn test_simple() {
- let x = Rc::new(5);
- assert_eq!(*x.borrow(), 5);
- }
-
- #[test]
- fn test_simple_clone() {
- let x = Rc::new(5);
- let y = x.clone();
- assert_eq!(*x.borrow(), 5);
- assert_eq!(*y.borrow(), 5);
- }
-
- #[test]
- fn test_destructor() {
- let x = Rc::from_send(~5);
- assert_eq!(**x.borrow(), 5);
- }
-
- #[test]
- fn test_from_mut() {
- let a = 10;
- let _x = Rc::from_mut(RefCell::new(&a));
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Runtime type reflection
-
-*/
-
-#[allow(missing_doc)];
-
-use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
-use libc::c_void;
-use mem;
-use unstable::raw;
-
-/**
- * Trait for visitor that wishes to reflect on data. To use this, create a
- * struct that encapsulates the set of pointers you wish to walk through a
- * data structure, and implement both `MovePtr` for it as well as `TyVisitor`;
- * then build a MovePtrAdaptor wrapped around your struct.
- */
-pub trait MovePtr {
- fn move_ptr(&mut self, adjustment: |*c_void| -> *c_void);
- fn push_ptr(&mut self);
- fn pop_ptr(&mut self);
-}
-
-/// Helper function for alignment calculation.
-#[inline]
-pub fn align(size: uint, align: uint) -> uint {
- ((size + align) - 1u) & !(align - 1u)
-}
-
-/// Adaptor to wrap around visitors implementing MovePtr.
-pub struct MovePtrAdaptor<V> {
- priv inner: V
-}
-pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
- MovePtrAdaptor { inner: v }
-}
-
-impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
- #[inline]
- pub fn bump(&mut self, sz: uint) {
- self.inner.move_ptr(|p| ((p as uint) + sz) as *c_void)
- }
-
- #[inline]
- pub fn align(&mut self, a: uint) {
- self.inner.move_ptr(|p| align(p as uint, a) as *c_void)
- }
-
- #[inline]
- pub fn align_to<T>(&mut self) {
- self.align(mem::min_align_of::<T>());
- }
-
- #[inline]
- pub fn bump_past<T>(&mut self) {
- self.bump(mem::size_of::<T>());
- }
-}
-
-/// Abstract type-directed pointer-movement using the MovePtr trait
-impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
- fn visit_bot(&mut self) -> bool {
- self.align_to::<()>();
- if ! self.inner.visit_bot() { return false; }
- self.bump_past::<()>();
- true
- }
-
- fn visit_nil(&mut self) -> bool {
- self.align_to::<()>();
- if ! self.inner.visit_nil() { return false; }
- self.bump_past::<()>();
- true
- }
-
- fn visit_bool(&mut self) -> bool {
- self.align_to::<bool>();
- if ! self.inner.visit_bool() { return false; }
- self.bump_past::<bool>();
- true
- }
-
- fn visit_int(&mut self) -> bool {
- self.align_to::<int>();
- if ! self.inner.visit_int() { return false; }
- self.bump_past::<int>();
- true
- }
-
- fn visit_i8(&mut self) -> bool {
- self.align_to::<i8>();
- if ! self.inner.visit_i8() { return false; }
- self.bump_past::<i8>();
- true
- }
-
- fn visit_i16(&mut self) -> bool {
- self.align_to::<i16>();
- if ! self.inner.visit_i16() { return false; }
- self.bump_past::<i16>();
- true
- }
-
- fn visit_i32(&mut self) -> bool {
- self.align_to::<i32>();
- if ! self.inner.visit_i32() { return false; }
- self.bump_past::<i32>();
- true
- }
-
- fn visit_i64(&mut self) -> bool {
- self.align_to::<i64>();
- if ! self.inner.visit_i64() { return false; }
- self.bump_past::<i64>();
- true
- }
-
- fn visit_uint(&mut self) -> bool {
- self.align_to::<uint>();
- if ! self.inner.visit_uint() { return false; }
- self.bump_past::<uint>();
- true
- }
-
- fn visit_u8(&mut self) -> bool {
- self.align_to::<u8>();
- if ! self.inner.visit_u8() { return false; }
- self.bump_past::<u8>();
- true
- }
-
- fn visit_u16(&mut self) -> bool {
- self.align_to::<u16>();
- if ! self.inner.visit_u16() { return false; }
- self.bump_past::<u16>();
- true
- }
-
- fn visit_u32(&mut self) -> bool {
- self.align_to::<u32>();
- if ! self.inner.visit_u32() { return false; }
- self.bump_past::<u32>();
- true
- }
-
- fn visit_u64(&mut self) -> bool {
- self.align_to::<u64>();
- if ! self.inner.visit_u64() { return false; }
- self.bump_past::<u64>();
- true
- }
-
- fn visit_f32(&mut self) -> bool {
- self.align_to::<f32>();
- if ! self.inner.visit_f32() { return false; }
- self.bump_past::<f32>();
- true
- }
-
- fn visit_f64(&mut self) -> bool {
- self.align_to::<f64>();
- if ! self.inner.visit_f64() { return false; }
- self.bump_past::<f64>();
- true
- }
-
- fn visit_char(&mut self) -> bool {
- self.align_to::<char>();
- if ! self.inner.visit_char() { return false; }
- self.bump_past::<char>();
- true
- }
-
- fn visit_estr_box(&mut self) -> bool {
- self.align_to::<@str>();
- if ! self.inner.visit_estr_box() { return false; }
- self.bump_past::<@str>();
- true
- }
-
- fn visit_estr_uniq(&mut self) -> bool {
- self.align_to::<~str>();
- if ! self.inner.visit_estr_uniq() { return false; }
- self.bump_past::<~str>();
- true
- }
-
- fn visit_estr_slice(&mut self) -> bool {
- self.align_to::<&'static str>();
- if ! self.inner.visit_estr_slice() { return false; }
- self.bump_past::<&'static str>();
- true
- }
-
- fn visit_estr_fixed(&mut self, n: uint,
- sz: uint,
- align: uint) -> bool {
- self.align(align);
- if ! self.inner.visit_estr_fixed(n, sz, align) { return false; }
- self.bump(sz);
- true
- }
-
- fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<@u8>();
- if ! self.inner.visit_box(mtbl, inner) { return false; }
- self.bump_past::<@u8>();
- true
- }
-
- fn visit_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<~u8>();
- if ! self.inner.visit_uniq(mtbl, inner) { return false; }
- self.bump_past::<~u8>();
- true
- }
-
- fn visit_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<~u8>();
- if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; }
- self.bump_past::<~u8>();
- true
- }
-
- fn visit_ptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<*u8>();
- if ! self.inner.visit_ptr(mtbl, inner) { return false; }
- self.bump_past::<*u8>();
- true
- }
-
- fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<&'static u8>();
- if ! self.inner.visit_rptr(mtbl, inner) { return false; }
- self.bump_past::<&'static u8>();
- true
- }
-
- fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<raw::Vec<()>>();
- if ! self.inner.visit_vec(mtbl, inner) { return false; }
- true
- }
-
- fn visit_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<~[u8]>();
- if ! self.inner.visit_vec(mtbl, inner) { return false; }
- self.bump_past::<~[u8]>();
- true
- }
-
- fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<@[u8]>();
- if ! self.inner.visit_evec_box(mtbl, inner) { return false; }
- self.bump_past::<@[u8]>();
- true
- }
-
- fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<~[u8]>();
- if ! self.inner.visit_evec_uniq(mtbl, inner) { return false; }
- self.bump_past::<~[u8]>();
- true
- }
-
- fn visit_evec_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<~[@u8]>();
- if ! self.inner.visit_evec_uniq_managed(mtbl, inner) { return false; }
- self.bump_past::<~[@u8]>();
- true
- }
-
- fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.align_to::<&'static [u8]>();
- if ! self.inner.visit_evec_slice(mtbl, inner) { return false; }
- self.bump_past::<&'static [u8]>();
- true
- }
-
- fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
- mtbl: uint, inner: *TyDesc) -> bool {
- self.align(align);
- if ! self.inner.visit_evec_fixed(n, sz, align, mtbl, inner) {
- return false;
- }
- self.bump(sz);
- true
- }
-
- fn visit_enter_rec(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
- self.align(align);
- if ! self.inner.visit_enter_rec(n_fields, sz, align) { return false; }
- true
- }
-
- fn visit_rec_field(&mut self, i: uint, name: &str,
- mtbl: uint, inner: *TyDesc) -> bool {
- unsafe { self.align((*inner).align); }
- if ! self.inner.visit_rec_field(i, name, mtbl, inner) {
- return false;
- }
- unsafe { self.bump((*inner).size); }
- true
- }
-
- fn visit_leave_rec(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
- if ! self.inner.visit_leave_rec(n_fields, sz, align) { return false; }
- true
- }
-
- fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint, sz: uint,
- align: uint) -> bool {
- self.align(align);
- if ! self.inner.visit_enter_class(name, named_fields, n_fields, sz, align) {
- return false;
- }
- true
- }
-
- fn visit_class_field(&mut self, i: uint, name: &str, named: bool, mtbl: uint,
- inner: *TyDesc) -> bool {
- unsafe { self.align((*inner).align); }
- if ! self.inner.visit_class_field(i, name, named, mtbl, inner) {
- return false;
- }
- unsafe { self.bump((*inner).size); }
- true
- }
-
- fn visit_leave_class(&mut self, name: &str, named_fields: bool, n_fields: uint, sz: uint,
- align: uint) -> bool {
- if ! self.inner.visit_leave_class(name, named_fields, n_fields, sz, align) {
- return false;
- }
- true
- }
-
- fn visit_enter_tup(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
- self.align(align);
- if ! self.inner.visit_enter_tup(n_fields, sz, align) { return false; }
- true
- }
-
- fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
- unsafe { self.align((*inner).align); }
- if ! self.inner.visit_tup_field(i, inner) { return false; }
- unsafe { self.bump((*inner).size); }
- true
- }
-
- fn visit_leave_tup(&mut self, n_fields: uint, sz: uint, align: uint) -> bool {
- if ! self.inner.visit_leave_tup(n_fields, sz, align) { return false; }
- true
- }
-
- fn visit_enter_fn(&mut self, purity: uint, proto: uint,
- n_inputs: uint, retstyle: uint) -> bool {
- if ! self.inner.visit_enter_fn(purity, proto, n_inputs, retstyle) {
- return false
- }
- true
- }
-
- fn visit_fn_input(&mut self, i: uint, mode: uint, inner: *TyDesc) -> bool {
- if ! self.inner.visit_fn_input(i, mode, inner) { return false; }
- true
- }
-
- fn visit_fn_output(&mut self, retstyle: uint, variadic: bool, inner: *TyDesc) -> bool {
- if ! self.inner.visit_fn_output(retstyle, variadic, inner) { return false; }
- true
- }
-
- fn visit_leave_fn(&mut self, purity: uint, proto: uint,
- n_inputs: uint, retstyle: uint) -> bool {
- if ! self.inner.visit_leave_fn(purity, proto, n_inputs, retstyle) {
- return false;
- }
- true
- }
-
- fn visit_enter_enum(&mut self, n_variants: uint,
- get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
- sz: uint, align: uint)
- -> bool {
- self.align(align);
- if ! self.inner.visit_enter_enum(n_variants, get_disr, sz, align) {
- return false;
- }
- true
- }
-
- fn visit_enter_enum_variant(&mut self, variant: uint,
- disr_val: Disr,
- n_fields: uint,
- name: &str) -> bool {
- if ! self.inner.visit_enter_enum_variant(variant, disr_val,
- n_fields, name) {
- return false;
- }
- true
- }
-
- fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool {
- self.inner.push_ptr();
- self.bump(offset);
- if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
- self.inner.pop_ptr();
- true
- }
-
- fn visit_leave_enum_variant(&mut self, variant: uint,
- disr_val: Disr,
- n_fields: uint,
- name: &str) -> bool {
- if ! self.inner.visit_leave_enum_variant(variant, disr_val,
- n_fields, name) {
- return false;
- }
- true
- }
-
- fn visit_leave_enum(&mut self, n_variants: uint,
- get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
- sz: uint, align: uint) -> bool {
- if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
- return false;
- }
- self.bump(sz);
- true
- }
-
- fn visit_trait(&mut self, name: &str) -> bool {
- self.align_to::<@TyVisitor>();
- if ! self.inner.visit_trait(name) { return false; }
- self.bump_past::<@TyVisitor>();
- true
- }
-
- fn visit_param(&mut self, i: uint) -> bool {
- if ! self.inner.visit_param(i) { return false; }
- true
- }
-
- fn visit_self(&mut self) -> bool {
- self.align_to::<&'static u8>();
- if ! self.inner.visit_self() { return false; }
- self.align_to::<&'static u8>();
- true
- }
-
- fn visit_type(&mut self) -> bool {
- if ! self.inner.visit_type() { return false; }
- true
- }
-
- fn visit_opaque_box(&mut self) -> bool {
- self.align_to::<@u8>();
- if ! self.inner.visit_opaque_box() { return false; }
- self.bump_past::<@u8>();
- true
- }
-
- fn visit_closure_ptr(&mut self, ck: uint) -> bool {
- self.align_to::<proc()>();
- if ! self.inner.visit_closure_ptr(ck) {
- return false
- }
- self.bump_past::<proc()>();
- true
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-More runtime type reflection
-
-*/
-
-#[allow(missing_doc)];
-
-use cast::transmute;
-use char;
-use container::Container;
-use io;
-use iter::Iterator;
-use libc::c_void;
-use option::{Some, None};
-use ptr;
-use reflect;
-use reflect::{MovePtr, align};
-use str::StrSlice;
-use to_str::ToStr;
-use vec::OwnedVector;
-use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
-use unstable::raw;
-
-/// Representations
-
-trait Repr {
- fn write_repr(&self, writer: &mut io::Writer);
-}
-
-impl Repr for () {
- fn write_repr(&self, writer: &mut io::Writer) {
- writer.write("()".as_bytes());
- }
-}
-
-impl Repr for bool {
- fn write_repr(&self, writer: &mut io::Writer) {
- let s = if *self { "true" } else { "false" };
- writer.write(s.as_bytes())
- }
-}
-
-impl Repr for int {
- fn write_repr(&self, writer: &mut io::Writer) {
- ::int::to_str_bytes(*self, 10u, |bits| {
- writer.write(bits);
- })
- }
-}
-
-macro_rules! int_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
- fn write_repr(&self, writer: &mut io::Writer) {
- ::$ty::to_str_bytes(*self, 10u, |bits| {
- writer.write(bits);
- writer.write(bytes!($suffix));
- })
- }
-}))
-
-int_repr!(i8, "i8")
-int_repr!(i16, "i16")
-int_repr!(i32, "i32")
-int_repr!(i64, "i64")
-int_repr!(uint, "u")
-int_repr!(u8, "u8")
-int_repr!(u16, "u16")
-int_repr!(u32, "u32")
-int_repr!(u64, "u64")
-
-macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
- fn write_repr(&self, writer: &mut io::Writer) {
- let s = self.to_str();
- writer.write(s.as_bytes());
- writer.write(bytes!($suffix));
- }
-}))
-
-num_repr!(f32, "f32")
-num_repr!(f64, "f64")
-
-// New implementation using reflect::MovePtr
-
-enum VariantState {
- SearchingFor(Disr),
- Matched,
- AlreadyFound
-}
-
-pub struct ReprVisitor<'self> {
- priv ptr: *c_void,
- priv ptr_stk: ~[*c_void],
- priv var_stk: ~[VariantState],
- priv writer: &'self mut io::Writer
-}
-
-pub fn ReprVisitor<'a>(ptr: *c_void,
- writer: &'a mut io::Writer) -> ReprVisitor<'a> {
- ReprVisitor {
- ptr: ptr,
- ptr_stk: ~[],
- var_stk: ~[],
- writer: writer,
- }
-}
-
-impl<'self> MovePtr for ReprVisitor<'self> {
- #[inline]
- fn move_ptr(&mut self, adjustment: |*c_void| -> *c_void) {
- self.ptr = adjustment(self.ptr);
- }
- fn push_ptr(&mut self) {
- self.ptr_stk.push(self.ptr);
- }
- fn pop_ptr(&mut self) {
- self.ptr = self.ptr_stk.pop();
- }
-}
-
-impl<'self> ReprVisitor<'self> {
- // Various helpers for the TyVisitor impl
-
- #[inline]
- pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T|) -> bool {
- unsafe {
- f(self, transmute::<*c_void,&T>(self.ptr));
- }
- true
- }
-
- #[inline]
- pub fn visit_inner(&mut self, inner: *TyDesc) -> bool {
- self.visit_ptr_inner(self.ptr, inner)
- }
-
- #[inline]
- pub fn visit_ptr_inner(&mut self, ptr: *c_void, inner: *TyDesc) -> bool {
- unsafe {
- // This should call the constructor up above, but due to limiting
- // issues we have to recreate it here.
- let u = ReprVisitor {
- ptr: ptr,
- ptr_stk: ~[],
- var_stk: ~[],
- writer: ::cast::transmute_copy(&self.writer),
- };
- let mut v = reflect::MovePtrAdaptor(u);
- // Obviously this should not be a thing, but blame #8401 for now
- visit_tydesc(inner, &mut v as &mut TyVisitor);
- true
- }
- }
-
- #[inline]
- pub fn write<T:Repr>(&mut self) -> bool {
- self.get(|this, v:&T| {
- v.write_repr(unsafe { ::cast::transmute_copy(&this.writer) });
- })
- }
-
- pub fn write_escaped_slice(&mut self, slice: &str) {
- self.writer.write(['"' as u8]);
- for ch in slice.chars() {
- self.write_escaped_char(ch, true);
- }
- self.writer.write(['"' as u8]);
- }
-
- pub fn write_mut_qualifier(&mut self, mtbl: uint) {
- if mtbl == 0 {
- self.writer.write("mut ".as_bytes());
- } else if mtbl == 1 {
- // skip, this is ast::m_imm
- } else {
- fail!("invalid mutability value");
- }
- }
-
- pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
- let mut p = ptr as *u8;
- let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
- self.writer.write(['[' as u8]);
- let mut first = true;
- let mut left = len;
- // unit structs have 0 size, and don't loop forever.
- let dec = if sz == 0 {1} else {sz};
- while left > 0 {
- if first {
- first = false;
- } else {
- self.writer.write(", ".as_bytes());
- }
- self.visit_ptr_inner(p as *c_void, inner);
- p = align(unsafe { ptr::offset(p, sz as int) as uint }, al) as *u8;
- left -= dec;
- }
- self.writer.write([']' as u8]);
- true
- }
-
- pub fn write_unboxed_vec_repr(&mut self, _: uint, v: &raw::Vec<()>, inner: *TyDesc) -> bool {
- self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner)
- }
-
- fn write_escaped_char(&mut self, ch: char, is_str: bool) {
- match ch {
- '\t' => self.writer.write("\\t".as_bytes()),
- '\r' => self.writer.write("\\r".as_bytes()),
- '\n' => self.writer.write("\\n".as_bytes()),
- '\\' => self.writer.write("\\\\".as_bytes()),
- '\'' => {
- if is_str {
- self.writer.write("'".as_bytes())
- } else {
- self.writer.write("\\'".as_bytes())
- }
- }
- '"' => {
- if is_str {
- self.writer.write("\\\"".as_bytes())
- } else {
- self.writer.write("\"".as_bytes())
- }
- }
- '\x20'..'\x7e' => self.writer.write([ch as u8]),
- _ => {
- char::escape_unicode(ch, |c| {
- self.writer.write([c as u8]);
- })
- }
- }
- }
-}
-
-impl<'self> TyVisitor for ReprVisitor<'self> {
- fn visit_bot(&mut self) -> bool {
- self.writer.write("!".as_bytes());
- true
- }
- fn visit_nil(&mut self) -> bool { self.write::<()>() }
- fn visit_bool(&mut self) -> bool { self.write::<bool>() }
- fn visit_int(&mut self) -> bool { self.write::<int>() }
- fn visit_i8(&mut self) -> bool { self.write::<i8>() }
- fn visit_i16(&mut self) -> bool { self.write::<i16>() }
- fn visit_i32(&mut self) -> bool { self.write::<i32>() }
- fn visit_i64(&mut self) -> bool { self.write::<i64>() }
-
- fn visit_uint(&mut self) -> bool { self.write::<uint>() }
- fn visit_u8(&mut self) -> bool { self.write::<u8>() }
- fn visit_u16(&mut self) -> bool { self.write::<u16>() }
- fn visit_u32(&mut self) -> bool { self.write::<u32>() }
- fn visit_u64(&mut self) -> bool { self.write::<u64>() }
-
- fn visit_f32(&mut self) -> bool { self.write::<f32>() }
- fn visit_f64(&mut self) -> bool { self.write::<f64>() }
-
- fn visit_char(&mut self) -> bool {
- self.get::<char>(|this, &ch| {
- this.writer.write(['\'' as u8]);
- this.write_escaped_char(ch, false);
- this.writer.write(['\'' as u8]);
- })
- }
-
- fn visit_estr_box(&mut self) -> bool {
- self.get::<@str>(|this, s| {
- this.writer.write(['@' as u8]);
- this.write_escaped_slice(*s);
- })
- }
-
- fn visit_estr_uniq(&mut self) -> bool {
- self.get::<~str>(|this, s| {
- this.writer.write(['~' as u8]);
- this.write_escaped_slice(*s);
- })
- }
-
- fn visit_estr_slice(&mut self) -> bool {
- self.get::<&str>(|this, s| this.write_escaped_slice(*s))
- }
-
- // Type no longer exists, vestigial function.
- fn visit_estr_fixed(&mut self, _n: uint, _sz: uint,
- _align: uint) -> bool { fail!(); }
-
- fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.writer.write(['@' as u8]);
- self.write_mut_qualifier(mtbl);
- self.get::<&raw::Box<()>>(|this, b| {
- let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
- this.visit_ptr_inner(p, inner);
- })
- }
-
- fn visit_uniq(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
- self.writer.write(['~' as u8]);
- self.get::<*c_void>(|this, b| {
- this.visit_ptr_inner(*b, inner);
- })
- }
-
- fn visit_uniq_managed(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
- self.writer.write(['~' as u8]);
- self.get::<&raw::Box<()>>(|this, b| {
- let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
- this.visit_ptr_inner(p, inner);
- })
- }
-
- fn visit_ptr(&mut self, mtbl: uint, _inner: *TyDesc) -> bool {
- self.get::<*c_void>(|this, p| {
- write!(this.writer, "({} as *", *p);
- this.write_mut_qualifier(mtbl);
- this.writer.write("())".as_bytes());
- })
- }
-
- fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.writer.write(['&' as u8]);
- self.write_mut_qualifier(mtbl);
- self.get::<*c_void>(|this, p| {
- this.visit_ptr_inner(*p, inner);
- })
- }
-
- // Type no longer exists, vestigial function.
- fn visit_vec(&mut self, _mtbl: uint, _inner: *TyDesc) -> bool { fail!(); }
-
- fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.get::<raw::Vec<()>>(|this, b| {
- this.write_unboxed_vec_repr(mtbl, b, inner);
- })
- }
-
- fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.get::<&raw::Box<raw::Vec<()>>>(|this, b| {
- this.writer.write(['@' as u8]);
- this.write_mut_qualifier(mtbl);
- this.write_unboxed_vec_repr(mtbl, &b.data, inner);
- })
- }
-
- fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.get::<&raw::Vec<()>>(|this, b| {
- this.writer.write(['~' as u8]);
- this.write_unboxed_vec_repr(mtbl, *b, inner);
- })
- }
-
- fn visit_evec_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.get::<&raw::Box<raw::Vec<()>>>(|this, b| {
- this.writer.write(['~' as u8]);
- this.write_unboxed_vec_repr(mtbl, &b.data, inner);
- })
- }
-
- fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
- self.get::<raw::Slice<()>>(|this, s| {
- this.writer.write(['&' as u8]);
- this.write_mut_qualifier(mtbl);
- let size = unsafe {
- if (*inner).size == 0 { 1 } else { (*inner).size }
- };
- this.write_vec_range(s.data, s.len * size, inner);
- })
- }
-
- fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
- _: uint, inner: *TyDesc) -> bool {
- let assumed_size = if sz == 0 { n } else { sz };
- self.get::<()>(|this, b| {
- this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner);
- })
- }
-
- fn visit_enter_rec(&mut self, _n_fields: uint,
- _sz: uint, _align: uint) -> bool {
- self.writer.write(['{' as u8]);
- true
- }
-
- fn visit_rec_field(&mut self, i: uint, name: &str,
- mtbl: uint, inner: *TyDesc) -> bool {
- if i != 0 {
- self.writer.write(", ".as_bytes());
- }
- self.write_mut_qualifier(mtbl);
- self.writer.write(name.as_bytes());
- self.writer.write(": ".as_bytes());
- self.visit_inner(inner);
- true
- }
-
- fn visit_leave_rec(&mut self, _n_fields: uint,
- _sz: uint, _align: uint) -> bool {
- self.writer.write(['}' as u8]);
- true
- }
-
- fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
- _sz: uint, _align: uint) -> bool {
- self.writer.write(name.as_bytes());
- if n_fields != 0 {
- if named_fields {
- self.writer.write(['{' as u8]);
- } else {
- self.writer.write(['(' as u8]);
- }
- }
- true
- }
-
- fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
- _mtbl: uint, inner: *TyDesc) -> bool {
- if i != 0 {
- self.writer.write(", ".as_bytes());
- }
- if named {
- self.writer.write(name.as_bytes());
- self.writer.write(": ".as_bytes());
- }
- self.visit_inner(inner);
- true
- }
-
- fn visit_leave_class(&mut self, _name: &str, named_fields: bool, n_fields: uint,
- _sz: uint, _align: uint) -> bool {
- if n_fields != 0 {
- if named_fields {
- self.writer.write(['}' as u8]);
- } else {
- self.writer.write([')' as u8]);
- }
- }
- true
- }
-
- fn visit_enter_tup(&mut self, _n_fields: uint,
- _sz: uint, _align: uint) -> bool {
- self.writer.write(['(' as u8]);
- true
- }
-
- fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
- if i != 0 {
- self.writer.write(", ".as_bytes());
- }
- self.visit_inner(inner);
- true
- }
-
- fn visit_leave_tup(&mut self, _n_fields: uint,
- _sz: uint, _align: uint) -> bool {
- if _n_fields == 1 {
- self.writer.write([',' as u8]);
- }
- self.writer.write([')' as u8]);
- true
- }
-
- fn visit_enter_enum(&mut self,
- _n_variants: uint,
- get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
- _sz: uint,
- _align: uint) -> bool {
- let disr = unsafe {
- get_disr(transmute(self.ptr))
- };
- self.var_stk.push(SearchingFor(disr));
- true
- }
-
- fn visit_enter_enum_variant(&mut self, _variant: uint,
- disr_val: Disr,
- n_fields: uint,
- name: &str) -> bool {
- let mut write = false;
- match self.var_stk.pop() {
- SearchingFor(sought) => {
- if disr_val == sought {
- self.var_stk.push(Matched);
- write = true;
- } else {
- self.var_stk.push(SearchingFor(sought));
- }
- }
- Matched | AlreadyFound => {
- self.var_stk.push(AlreadyFound);
- }
- }
-
- if write {
- self.writer.write(name.as_bytes());
- if n_fields > 0 {
- self.writer.write(['(' as u8]);
- }
- }
- true
- }
-
- fn visit_enum_variant_field(&mut self,
- i: uint,
- _offset: uint,
- inner: *TyDesc)
- -> bool {
- match self.var_stk[self.var_stk.len() - 1] {
- Matched => {
- if i != 0 {
- self.writer.write(", ".as_bytes());
- }
- if ! self.visit_inner(inner) {
- return false;
- }
- }
- _ => ()
- }
- true
- }
-
- fn visit_leave_enum_variant(&mut self, _variant: uint,
- _disr_val: Disr,
- n_fields: uint,
- _name: &str) -> bool {
- match self.var_stk[self.var_stk.len() - 1] {
- Matched => {
- if n_fields > 0 {
- self.writer.write([')' as u8]);
- }
- }
- _ => ()
- }
- true
- }
-
- fn visit_leave_enum(&mut self,
- _n_variants: uint,
- _get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
- _sz: uint,
- _align: uint)
- -> bool {
- match self.var_stk.pop() {
- SearchingFor(..) => fail!("enum value matched no variant"),
- _ => true
- }
- }
-
- fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
- _n_inputs: uint, _retstyle: uint) -> bool {
- self.writer.write("fn(".as_bytes());
- true
- }
-
- fn visit_fn_input(&mut self, i: uint, _mode: uint, inner: *TyDesc) -> bool {
- if i != 0 {
- self.writer.write(", ".as_bytes());
- }
- let name = unsafe { (*inner).name };
- self.writer.write(name.as_bytes());
- true
- }
-
- fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool, inner: *TyDesc) -> bool {
- if variadic {
- self.writer.write(", ...".as_bytes());
- }
- self.writer.write(")".as_bytes());
- let name = unsafe { (*inner).name };
- if name != "()" {
- self.writer.write(" -> ".as_bytes());
- self.writer.write(name.as_bytes());
- }
- true
- }
-
- fn visit_leave_fn(&mut self, _purity: uint, _proto: uint,
- _n_inputs: uint, _retstyle: uint) -> bool { true }
-
-
- fn visit_trait(&mut self, name: &str) -> bool {
- self.writer.write(name.as_bytes());
- true
- }
-
- fn visit_param(&mut self, _i: uint) -> bool { true }
- fn visit_self(&mut self) -> bool { true }
- fn visit_type(&mut self) -> bool { true }
-
- fn visit_opaque_box(&mut self) -> bool {
- self.writer.write(['@' as u8]);
- self.get::<&raw::Box<()>>(|this, b| {
- let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
- this.visit_ptr_inner(p, b.type_desc);
- })
- }
-
- fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
-}
-
-pub fn write_repr<T>(writer: &mut io::Writer, object: &T) {
- unsafe {
- let ptr = ptr::to_unsafe_ptr(object) as *c_void;
- let tydesc = get_tydesc::<T>();
- let u = ReprVisitor(ptr, writer);
- let mut v = reflect::MovePtrAdaptor(u);
- visit_tydesc(tydesc, &mut v as &mut TyVisitor);
- }
-}
-
-pub fn repr_to_str<T>(t: &T) -> ~str {
- use str;
- use io;
- use io::Decorator;
-
- let mut result = io::mem::MemWriter::new();
- write_repr(&mut result as &mut io::Writer, t);
- str::from_utf8_owned(result.inner())
-}
-
-#[cfg(test)]
-struct P {a: int, b: f64}
-
-#[test]
-fn test_repr() {
- use prelude::*;
- use str;
- use str::Str;
- use io::Decorator;
- use util::swap;
- use char::is_alphabetic;
-
- fn exact_test<T>(t: &T, e:&str) {
- let mut m = io::mem::MemWriter::new();
- write_repr(&mut m as &mut io::Writer, t);
- let s = str::from_utf8_owned(m.inner());
- assert_eq!(s.as_slice(), e);
- }
-
- exact_test(&10, "10");
- exact_test(&true, "true");
- exact_test(&false, "false");
- exact_test(&1.234, "1.234f64");
- exact_test(&(&"hello"), "\"hello\"");
- exact_test(&(@"hello"), "@\"hello\"");
- exact_test(&(~"he\u10f3llo"), "~\"he\\u10f3llo\"");
-
- exact_test(&(@10), "@10");
- exact_test(&(@mut 10), "@mut 10");
- exact_test(&((@mut 10, 2)), "(@mut 10, 2)");
- exact_test(&(~10), "~10");
- exact_test(&(&10), "&10");
- let mut x = 10;
- exact_test(&(&mut x), "&mut 10");
- exact_test(&(@mut [1, 2]), "@mut [1, 2]");
-
- exact_test(&(0 as *()), "(0x0 as *())");
- exact_test(&(0 as *mut ()), "(0x0 as *mut ())");
-
- exact_test(&(1,), "(1,)");
- exact_test(&(@[1,2,3,4,5,6,7,8]),
- "@[1, 2, 3, 4, 5, 6, 7, 8]");
- exact_test(&(@[1u8,2u8,3u8,4u8]),
- "@[1u8, 2u8, 3u8, 4u8]");
- exact_test(&(@["hi", "there"]),
- "@[\"hi\", \"there\"]");
- exact_test(&(~["hi", "there"]),
- "~[\"hi\", \"there\"]");
- exact_test(&(&["hi", "there"]),
- "&[\"hi\", \"there\"]");
- exact_test(&(P{a:10, b:1.234}),
- "repr::P{a: 10, b: 1.234f64}");
- exact_test(&(@P{a:10, b:1.234}),
- "@repr::P{a: 10, b: 1.234f64}");
- exact_test(&(~P{a:10, b:1.234}),
- "~repr::P{a: 10, b: 1.234f64}");
- exact_test(&(10u8, ~"hello"),
- "(10u8, ~\"hello\")");
- exact_test(&(10u16, ~"hello"),
- "(10u16, ~\"hello\")");
- exact_test(&(10u32, ~"hello"),
- "(10u32, ~\"hello\")");
- exact_test(&(10u64, ~"hello"),
- "(10u64, ~\"hello\")");
-
- exact_test(&(&[1, 2]), "&[1, 2]");
- exact_test(&(&mut [1, 2]), "&mut [1, 2]");
-
- exact_test(&'\'', "'\\''");
- exact_test(&'"', "'\"'");
- exact_test(&("'"), "\"'\"");
- exact_test(&("\""), "\"\\\"\"");
-
- exact_test(&println, "fn(&str)");
- exact_test(&swap::<int>, "fn(&mut int, &mut int)");
- exact_test(&is_alphabetic, "fn(char) -> bool");
- exact_test(&(~5 as ~ToStr), "~to_str::ToStr:Send");
-
- struct Foo;
- exact_test(&(~[Foo, Foo]), "~[repr::test_repr::Foo, repr::test_repr::Foo]");
-
- struct Bar(int, int);
- exact_test(&(Bar(2, 2)), "repr::test_repr::Bar(2, 2)");
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A type representing either success or failure
-
-use any::Any;
-use clone::Clone;
-use cmp::Eq;
-use fmt;
-use iter::Iterator;
-use kinds::Send;
-use option::{None, Option, Some, OptionIterator};
-use option::{ToOption, IntoOption, AsOption};
-use str::OwnedStr;
-use to_str::ToStr;
-use vec::OwnedVector;
-use vec;
-
-/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
-///
-/// In order to provide informative error messages, `E` is required to implement `ToStr`.
-/// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
-/// all possible errors cases.
-#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
-pub enum Result<T, E> {
- /// Contains the successful result value
- Ok(T),
- /// Contains the error value
- Err(E)
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Type implementation
-/////////////////////////////////////////////////////////////////////////////
-
-impl<T, E: ToStr> Result<T, E> {
- /////////////////////////////////////////////////////////////////////////
- // Querying the contained values
- /////////////////////////////////////////////////////////////////////////
-
- /// Returns true if the result is `Ok`
- #[inline]
- pub fn is_ok(&self) -> bool {
- match *self {
- Ok(_) => true,
- Err(_) => false
- }
- }
-
- /// Returns true if the result is `Err`
- #[inline]
- pub fn is_err(&self) -> bool {
- !self.is_ok()
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Adapter for working with references
- /////////////////////////////////////////////////////////////////////////
-
- /// Convert from `Result<T, E>` to `Result<&T, &E>`
- #[inline]
- pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
- match *self {
- Ok(ref x) => Ok(x),
- Err(ref x) => Err(x),
- }
- }
-
- /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
- #[inline]
- pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
- match *self {
- Ok(ref mut x) => Ok(x),
- Err(ref mut x) => Err(x),
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Getting to contained values
- /////////////////////////////////////////////////////////////////////////
-
- /// Unwraps a result, yielding the content of an `Ok`.
- /// Fails if the value is a `Err` with a custom failure message provided by `msg`.
- #[inline]
- pub fn expect<M: Any + Send>(self, msg: M) -> T {
- match self {
- Ok(t) => t,
- Err(_) => fail!(msg),
- }
- }
-
- /// Unwraps a result, yielding the content of an `Err`.
- /// Fails if the value is a `Ok` with a custom failure message provided by `msg`.
- #[inline]
- pub fn expect_err<M: Any + Send>(self, msg: M) -> E {
- match self {
- Err(e) => e,
- Ok(_) => fail!(msg),
- }
- }
-
- /// Unwraps a result, yielding the content of an `Ok`.
- /// Fails if the value is a `Err` with an error message derived
- /// from `E`'s `ToStr` implementation.
- #[inline]
- pub fn unwrap(self) -> T {
- match self {
- Ok(t) => t,
- Err(e) => fail!("called `Result::unwrap()` on `Err` value '{}'",
- e.to_str()),
- }
- }
-
- /// Unwraps a result, yielding the content of an `Err`.
- /// Fails if the value is a `Ok`.
- #[inline]
- pub fn unwrap_err(self) -> E {
- match self {
- Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"),
- Err(e) => e
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Transforming contained values
- /////////////////////////////////////////////////////////////////////////
-
- /// Maps an `Result<T, E>` to `Result<U, E>` by applying a function to an
- /// contained `Ok` value, leaving an `Err` value untouched.
- ///
- /// This function can be used to compose the results of two functions.
- ///
- /// Example:
- ///
- /// let res = read_file(file).map(|buf| {
- /// parse_bytes(buf)
- /// })
- #[inline]
- pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
- match self {
- Ok(t) => Ok(op(t)),
- Err(e) => Err(e)
- }
- }
-
- /// Maps an `Result<T, E>` to `Result<T, F>` by applying a function to an
- /// contained `Err` value, leaving an `Ok` value untouched.
- ///
- /// This function can be used to pass through a successful result while handling
- /// an error.
- #[inline]
- pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
- match self {
- Ok(t) => Ok(t),
- Err(e) => Err(op(e))
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Iterator constructors
- /////////////////////////////////////////////////////////////////////////
-
- /// Returns an `Iterator` over one or zero references to the value of an `Ok`
- ///
- /// Example:
- ///
- /// for buf in read_file(file) {
- /// print_buf(buf)
- /// }
- #[inline]
- pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
- match *self {
- Ok(ref t) => Some(t),
- Err(..) => None,
- }.move_iter()
- }
-
- /// Returns an `Iterator` over one or zero references to the value of an `Err`
- #[inline]
- pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
- match *self {
- Ok(..) => None,
- Err(ref t) => Some(t),
- }.move_iter()
- }
-
- ////////////////////////////////////////////////////////////////////////
- // Boolean operations on the values, eager and lazy
- /////////////////////////////////////////////////////////////////////////
-
- /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
- #[inline]
- pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
- match self {
- Ok(_) => res,
- Err(e) => Err(e),
- }
- }
-
- /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
- ///
- /// This function can be used for control flow based on result values
- #[inline]
- pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
- match self {
- Ok(t) => op(t),
- Err(e) => Err(e),
- }
- }
-
- /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
- #[inline]
- pub fn or(self, res: Result<T, E>) -> Result<T, E> {
- match self {
- Ok(_) => self,
- Err(_) => res,
- }
- }
-
- /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
- ///
- /// This function can be used for control flow based on result values
- #[inline]
- pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
- match self {
- Ok(t) => Ok(t),
- Err(e) => op(e),
- }
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Common special cases
- /////////////////////////////////////////////////////////////////////////
-
- /// Get a reference to the value out of a successful result
- ///
- /// # Failure
- ///
- /// If the result is an error
- #[inline]
- pub fn get_ref<'a>(&'a self) -> &'a T {
- match *self {
- Ok(ref t) => t,
- Err(ref e) => fail!("called `Result::get_ref()` on `Err` value '{}'",
- e.to_str()),
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Constructor extension trait
-/////////////////////////////////////////////////////////////////////////////
-
-/// A generic trait for converting a value to a `Result`
-pub trait ToResult<T, E> {
- /// Convert to the `result` type
- fn to_result(&self) -> Result<T, E>;
-}
-
-/// A generic trait for converting a value to a `Result`
-pub trait IntoResult<T, E> {
- /// Convert to the `result` type
- fn into_result(self) -> Result<T, E>;
-}
-
-/// A generic trait for converting a value to a `Result`
-pub trait AsResult<T, E> {
- /// Convert to the `result` type
- fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
-}
-
-impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
- #[inline]
- fn to_result(&self) -> Result<T, E> { self.clone() }
-}
-
-impl<T, E> IntoResult<T, E> for Result<T, E> {
- #[inline]
- fn into_result(self) -> Result<T, E> { self }
-}
-
-impl<T, E> AsResult<T, E> for Result<T, E> {
- #[inline]
- fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
- match *self {
- Ok(ref t) => Ok(t),
- Err(ref e) => Err(e),
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Trait implementations
-/////////////////////////////////////////////////////////////////////////////
-
-impl<T: Clone, E> ToOption<T> for Result<T, E> {
- #[inline]
- fn to_option(&self) -> Option<T> {
- match *self {
- Ok(ref t) => Some(t.clone()),
- Err(_) => None,
- }
- }
-}
-
-impl<T, E> IntoOption<T> for Result<T, E> {
- #[inline]
- fn into_option(self) -> Option<T> {
- match self {
- Ok(t) => Some(t),
- Err(_) => None,
- }
- }
-}
-
-impl<T, E> AsOption<T> for Result<T, E> {
- #[inline]
- fn as_option<'a>(&'a self) -> Option<&'a T> {
- match *self {
- Ok(ref t) => Some(t),
- Err(_) => None,
- }
- }
-}
-
-impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
- #[inline]
- fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
- match *s {
- Ok(ref t) => write!(f.buf, "Ok({})", *t),
- Err(ref e) => write!(f.buf, "Err({})", *e)
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Free functions
-/////////////////////////////////////////////////////////////////////////////
-
-/// Takes each element in the iterator: if it is an error, no further
-/// elements are taken, and the error is returned.
-/// Should no error occur, a vector containing the values of each Result
-/// is returned.
-///
-/// Here is an example which increments every integer in a vector,
-/// checking for overflow:
-///
-/// fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
-/// if x == uint::max_value { return Err("overflow"); }
-/// else { return Ok(x+1u); }
-/// }
-/// let v = [1u, 2, 3];
-/// let res = collect(v.iter().map(|&x| inc_conditionally(x)));
-/// assert!(res == Ok(~[2u, 3, 4]));
-#[inline]
-pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
- -> Result<~[T], E> {
- let (lower, _) = iterator.size_hint();
- let mut vs: ~[T] = vec::with_capacity(lower);
- for t in iterator {
- match t {
- Ok(v) => vs.push(v),
- Err(u) => return Err(u)
- }
- }
- Ok(vs)
-}
-
-/// Perform a fold operation over the result values from an iterator.
-///
-/// If an `Err` is encountered, it is immediately returned.
-/// Otherwise, the folded value is returned.
-#[inline]
-pub fn fold<T,
- V,
- E,
- Iter: Iterator<Result<T, E>>>(
- mut iterator: Iter,
- mut init: V,
- f: |V, T| -> V)
- -> Result<V, E> {
- for t in iterator {
- match t {
- Ok(v) => init = f(init, v),
- Err(u) => return Err(u)
- }
- }
- Ok(init)
-}
-
-/// Perform a trivial fold operation over the result values
-/// from an iterator.
-///
-/// If an `Err` is encountered, it is immediately returned.
-/// Otherwise, a simple `Ok(())` is returned.
-#[inline]
-pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
- fold(iterator, (), |_, _| ())
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Tests
-/////////////////////////////////////////////////////////////////////////////
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use iter::range;
- use option::{IntoOption, ToOption, AsOption};
- use option::{Some, None};
- use vec::ImmutableVector;
- use to_str::ToStr;
-
- pub fn op1() -> Result<int, ~str> { Ok(666) }
- pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
-
- #[test]
- pub fn test_and() {
- assert_eq!(op1().and(Ok(667)).unwrap(), 667);
- assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad");
-
- assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
- assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface");
- }
-
- #[test]
- pub fn test_and_then() {
- assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
- assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");
-
- assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
- assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
- }
-
- #[test]
- pub fn test_or() {
- assert_eq!(op1().or(Ok(667)).unwrap(), 666);
- assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
-
- assert_eq!(op2().or(Ok(667)).unwrap(), 667);
- assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
- }
-
- #[test]
- pub fn test_or_else() {
- assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
- assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);
-
- assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
- assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
- }
-
- #[test]
- pub fn test_impl_iter() {
- let mut valid = false;
- let okval = Ok::<~str, ~str>(~"a");
- okval.iter().next().map(|_| { valid = true; });
- assert!(valid);
-
- let errval = Err::<~str, ~str>(~"b");
- errval.iter().next().map(|_| { valid = false; });
- assert!(valid);
- }
-
- #[test]
- pub fn test_impl_iter_err() {
- let mut valid = true;
- let okval = Ok::<~str, ~str>(~"a");
- okval.iter_err().next().map(|_| { valid = false });
- assert!(valid);
-
- valid = false;
- let errval = Err::<~str, ~str>(~"b");
- errval.iter_err().next().map(|_| { valid = true });
- assert!(valid);
- }
-
- #[test]
- pub fn test_impl_map() {
- assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab"));
- assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a"));
- }
-
- #[test]
- pub fn test_impl_map_err() {
- assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a"));
- assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab"));
- }
-
- #[test]
- pub fn test_get_ref_method() {
- let foo: Result<int, ()> = Ok(100);
- assert_eq!(*foo.get_ref(), 100);
- }
-
- #[test]
- fn test_collect() {
- assert_eq!(collect(range(0, 0)
- .map(|_| Ok::<int, ()>(0))),
- Ok(~[]));
- assert_eq!(collect(range(0, 3)
- .map(|x| Ok::<int, ()>(x))),
- Ok(~[0, 1, 2]));
- assert_eq!(collect(range(0, 3)
- .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
- Err(2));
-
- // test that it does not take more elements than it needs
- let functions = [|| Ok(()), || Err(1), || fail!()];
-
- assert_eq!(collect(functions.iter().map(|f| (*f)())),
- Err(1));
- }
-
- #[test]
- fn test_fold() {
- assert_eq!(fold_(range(0, 0)
- .map(|_| Ok::<(), ()>(()))),
- Ok(()));
- assert_eq!(fold(range(0, 3)
- .map(|x| Ok::<int, ()>(x)),
- 0, |a, b| a + b),
- Ok(3));
- assert_eq!(fold_(range(0, 3)
- .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
- Err(2));
-
- // test that it does not take more elements than it needs
- let functions = [|| Ok(()), || Err(1), || fail!()];
-
- assert_eq!(fold_(functions.iter()
- .map(|f| (*f)())),
- Err(1));
- }
-
- #[test]
- pub fn test_to_option() {
- let ok: Result<int, int> = Ok(100);
- let err: Result<int, int> = Err(404);
-
- assert_eq!(ok.to_option(), Some(100));
- assert_eq!(err.to_option(), None);
- }
-
- #[test]
- pub fn test_into_option() {
- let ok: Result<int, int> = Ok(100);
- let err: Result<int, int> = Err(404);
-
- assert_eq!(ok.into_option(), Some(100));
- assert_eq!(err.into_option(), None);
- }
-
- #[test]
- pub fn test_as_option() {
- let ok: Result<int, int> = Ok(100);
- let err: Result<int, int> = Err(404);
-
- assert_eq!(ok.as_option().unwrap(), &100);
- assert_eq!(err.as_option(), None);
- }
-
- #[test]
- pub fn test_to_result() {
- let ok: Result<int, int> = Ok(100);
- let err: Result<int, int> = Err(404);
-
- assert_eq!(ok.to_result(), Ok(100));
- assert_eq!(err.to_result(), Err(404));
- }
-
- #[test]
- pub fn test_into_result() {
- let ok: Result<int, int> = Ok(100);
- let err: Result<int, int> = Err(404);
-
- assert_eq!(ok.into_result(), Ok(100));
- assert_eq!(err.into_result(), Err(404));
- }
-
- #[test]
- pub fn test_as_result() {
- let ok: Result<int, int> = Ok(100);
- let err: Result<int, int> = Err(404);
-
- let x = 100;
- assert_eq!(ok.as_result(), Ok(&x));
-
- let x = 404;
- assert_eq!(err.as_result(), Err(&x));
- }
-
- #[test]
- pub fn test_to_str() {
- let ok: Result<int, ~str> = Ok(100);
- let err: Result<int, ~str> = Err(~"Err");
-
- assert_eq!(ok.to_str(), ~"Ok(100)");
- assert_eq!(err.to_str(), ~"Err(Err)");
- }
-
- #[test]
- pub fn test_fmt_default() {
- let ok: Result<int, ~str> = Ok(100);
- let err: Result<int, ~str> = Err(~"Err");
-
- assert_eq!(format!("{}", ok), ~"Ok(100)");
- assert_eq!(format!("{}", err), ~"Err(Err)");
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Global storage for command line arguments
-//!
-//! The current incarnation of the Rust runtime expects for
-//! the processes `argc` and `argv` arguments to be stored
-//! in a globally-accessible location for use by the `os` module.
-//!
-//! Only valid to call on linux. Mac and Windows use syscalls to
-//! discover the command line arguments.
-//!
-//! FIXME #7756: Would be nice for this to not exist.
-//! FIXME #7756: This has a lot of C glue for lack of globals.
-
-use option::Option;
-#[cfg(test)] use option::{Some, None};
-#[cfg(test)] use realstd;
-#[cfg(test)] use realargs = realstd::rt::args;
-
-/// One-time global initialization.
-#[cfg(not(test))]
-pub unsafe fn init(argc: int, argv: **u8) { imp::init(argc, argv) }
-#[cfg(test)]
-pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
-
-/// One-time global cleanup.
-#[cfg(not(test))] pub unsafe fn cleanup() { imp::cleanup() }
-#[cfg(test)] pub unsafe fn cleanup() { realargs::cleanup() }
-
-/// Take the global arguments from global storage.
-#[cfg(not(test))] pub fn take() -> Option<~[~str]> { imp::take() }
-#[cfg(test)] pub fn take() -> Option<~[~str]> {
- match realargs::take() {
- realstd::option::Some(a) => Some(a),
- realstd::option::None => None,
- }
-}
-
-/// Give the global arguments to global storage.
-///
-/// It is an error if the arguments already exist.
-#[cfg(not(test))] pub fn put(args: ~[~str]) { imp::put(args) }
-#[cfg(test)] pub fn put(args: ~[~str]) { realargs::put(args) }
-
-/// Make a clone of the global arguments.
-#[cfg(not(test))] pub fn clone() -> Option<~[~str]> { imp::clone() }
-#[cfg(test)] pub fn clone() -> Option<~[~str]> {
- match realargs::clone() {
- realstd::option::Some(a) => Some(a),
- realstd::option::None => None,
- }
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")]
-mod imp {
- use cast;
- use libc;
- use option::{Option, Some, None};
- use iter::Iterator;
- use str;
- use unstable::finally::Finally;
- use unstable::mutex::{Mutex, MUTEX_INIT};
- use util;
- use vec;
-
- static mut global_args_ptr: uint = 0;
- static mut lock: Mutex = MUTEX_INIT;
-
- pub unsafe fn init(argc: int, argv: **u8) {
- let args = load_argc_and_argv(argc, argv);
- put(args);
- }
-
- pub unsafe fn cleanup() {
- rtassert!(take().is_some());
- lock.destroy();
- }
-
- pub fn take() -> Option<~[~str]> {
- with_lock(|| unsafe {
- let ptr = get_global_ptr();
- let val = util::replace(&mut *ptr, None);
- val.as_ref().map(|s: &~~[~str]| (**s).clone())
- })
- }
-
- pub fn put(args: ~[~str]) {
- with_lock(|| unsafe {
- let ptr = get_global_ptr();
- rtassert!((*ptr).is_none());
- (*ptr) = Some(~args.clone());
- })
- }
-
- pub fn clone() -> Option<~[~str]> {
- with_lock(|| unsafe {
- let ptr = get_global_ptr();
- (*ptr).as_ref().map(|s: &~~[~str]| (**s).clone())
- })
- }
-
- fn with_lock<T>(f: || -> T) -> T {
- (|| {
- unsafe {
- lock.lock();
- f()
- }
- }).finally(|| {
- unsafe {
- lock.unlock();
- }
- })
- }
-
- fn get_global_ptr() -> *mut Option<~~[~str]> {
- unsafe { cast::transmute(&global_args_ptr) }
- }
-
- // Copied from `os`.
- unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
- vec::from_fn(argc as uint, |i| {
- str::raw::from_c_str(*(argv as **libc::c_char).offset(i as int))
- })
- }
-
- #[cfg(test)]
- mod tests {
- use option::{Some, None};
- use super::*;
- use unstable::finally::Finally;
-
- #[test]
- fn smoke_test() {
- // Preserve the actual global state.
- let saved_value = take();
-
- let expected = ~[~"happy", ~"today?"];
-
- put(expected.clone());
- assert!(clone() == Some(expected.clone()));
- assert!(take() == Some(expected.clone()));
- assert!(take() == None);
-
- (|| {
- }).finally(|| {
- // Restore the actual global state.
- match saved_value {
- Some(ref args) => put(args.clone()),
- None => ()
- }
- })
- }
- }
-}
-
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "win32")]
-mod imp {
- use option::Option;
-
- pub unsafe fn init(_argc: int, _argv: **u8) {
- }
-
- pub fn cleanup() {
- }
-
- pub fn take() -> Option<~[~str]> {
- fail!()
- }
-
- pub fn put(_args: ~[~str]) {
- fail!()
- }
-
- pub fn clone() -> Option<~[~str]> {
- fail!()
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This is a basic event loop implementation not meant for any "real purposes"
-//! other than testing the scheduler and proving that it's possible to have a
-//! pluggable event loop.
-
-use prelude::*;
-
-use cast;
-use rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausibleIdleCallback,
- Callback};
-use unstable::sync::Exclusive;
-use io::native;
-use util;
-
-/// This is the only exported function from this module.
-pub fn event_loop() -> ~EventLoop {
- ~BasicLoop::new() as ~EventLoop
-}
-
-struct BasicLoop {
- work: ~[proc()], // pending work
- idle: Option<*mut BasicPausible>, // only one is allowed
- remotes: ~[(uint, ~Callback)],
- next_remote: uint,
- messages: Exclusive<~[Message]>,
- io: ~IoFactory,
-}
-
-enum Message { RunRemote(uint), RemoveRemote(uint) }
-
-struct Time {
- sec: u64,
- nsec: u64,
-}
-
-impl Ord for Time {
- fn lt(&self, other: &Time) -> bool {
- self.sec < other.sec || self.nsec < other.nsec
- }
-}
-
-impl BasicLoop {
- fn new() -> BasicLoop {
- BasicLoop {
- work: ~[],
- idle: None,
- next_remote: 0,
- remotes: ~[],
- messages: Exclusive::new(~[]),
- io: ~native::IoFactory as ~IoFactory,
- }
- }
-
- /// Process everything in the work queue (continually)
- fn work(&mut self) {
- while self.work.len() > 0 {
- for work in util::replace(&mut self.work, ~[]).move_iter() {
- work();
- }
- }
- }
-
- fn remote_work(&mut self) {
- let messages = unsafe {
- self.messages.with(|messages| {
- if messages.len() > 0 {
- Some(util::replace(messages, ~[]))
- } else {
- None
- }
- })
- };
- let messages = match messages {
- Some(m) => m, None => return
- };
- for message in messages.iter() {
- self.message(*message);
- }
- }
-
- fn message(&mut self, message: Message) {
- match message {
- RunRemote(i) => {
- match self.remotes.mut_iter().find(|& &(id, _)| id == i) {
- Some(&(_, ref mut f)) => f.call(),
- None => unreachable!()
- }
- }
- RemoveRemote(i) => {
- match self.remotes.iter().position(|&(id, _)| id == i) {
- Some(i) => { self.remotes.remove(i); }
- None => unreachable!()
- }
- }
- }
- }
-
- /// Run the idle callback if one is registered
- fn idle(&mut self) {
- unsafe {
- match self.idle {
- Some(idle) => {
- if (*idle).active {
- (*idle).work.call();
- }
- }
- None => {}
- }
- }
- }
-
- fn has_idle(&self) -> bool {
- unsafe { self.idle.is_some() && (**self.idle.get_ref()).active }
- }
-}
-
-impl EventLoop for BasicLoop {
- fn run(&mut self) {
- // Not exactly efficient, but it gets the job done.
- while self.remotes.len() > 0 || self.work.len() > 0 || self.has_idle() {
-
- self.work();
- self.remote_work();
-
- if self.has_idle() {
- self.idle();
- continue
- }
-
- unsafe {
- // We block here if we have no messages to process and we may
- // receive a message at a later date
- self.messages.hold_and_wait(|messages| {
- self.remotes.len() > 0 &&
- messages.len() == 0 &&
- self.work.len() == 0
- })
- }
- }
- }
-
- fn callback(&mut self, f: proc()) {
- self.work.push(f);
- }
-
- // XXX: Seems like a really weird requirement to have an event loop provide.
- fn pausible_idle_callback(&mut self, cb: ~Callback) -> ~PausibleIdleCallback {
- let callback = ~BasicPausible::new(self, cb);
- rtassert!(self.idle.is_none());
- unsafe {
- let cb_ptr: &*mut BasicPausible = cast::transmute(&callback);
- self.idle = Some(*cb_ptr);
- }
- return callback as ~PausibleIdleCallback;
- }
-
- fn remote_callback(&mut self, f: ~Callback) -> ~RemoteCallback {
- let id = self.next_remote;
- self.next_remote += 1;
- self.remotes.push((id, f));
- ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
- }
-
- fn io<'a>(&'a mut self, f: |&'a mut IoFactory|) {
- f(self.io)
- }
-}
-
-struct BasicRemote {
- queue: Exclusive<~[Message]>,
- id: uint,
-}
-
-impl BasicRemote {
- fn new(queue: Exclusive<~[Message]>, id: uint) -> BasicRemote {
- BasicRemote { queue: queue, id: id }
- }
-}
-
-impl RemoteCallback for BasicRemote {
- fn fire(&mut self) {
- unsafe {
- self.queue.hold_and_signal(|queue| {
- queue.push(RunRemote(self.id));
- })
- }
- }
-}
-
-impl Drop for BasicRemote {
- fn drop(&mut self) {
- unsafe {
- self.queue.hold_and_signal(|queue| {
- queue.push(RemoveRemote(self.id));
- })
- }
- }
-}
-
-struct BasicPausible {
- eloop: *mut BasicLoop,
- work: ~Callback,
- active: bool,
-}
-
-impl BasicPausible {
- fn new(eloop: &mut BasicLoop, cb: ~Callback) -> BasicPausible {
- BasicPausible {
- active: false,
- work: cb,
- eloop: eloop,
- }
- }
-}
-
-impl PausibleIdleCallback for BasicPausible {
- fn pause(&mut self) {
- self.active = false;
- }
- fn resume(&mut self) {
- self.active = true;
- }
-}
-
-impl Drop for BasicPausible {
- fn drop(&mut self) {
- unsafe {
- (*self.eloop).idle = None;
- }
- }
-}
-
-fn time() -> Time {
- extern {
- fn rust_get_time(sec: &mut i64, nsec: &mut i32);
- }
- let mut sec = 0;
- let mut nsec = 0;
- unsafe { rust_get_time(&mut sec, &mut nsec) }
-
- Time { sec: sec as u64, nsec: nsec as u64 }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cell::Cell;
-use c_str::{ToCStr, CString};
-use libc::{c_char, size_t};
-use option::{Option, None, Some};
-use ptr::RawPtr;
-use rt::env;
-use rt::local::Local;
-use rt::task;
-use rt::task::Task;
-use str::OwnedStr;
-use str;
-use uint;
-use unstable::raw;
-use vec::ImmutableVector;
-
-pub static FROZEN_BIT: uint = 1 << (uint::bits - 1);
-pub static MUT_BIT: uint = 1 << (uint::bits - 2);
-static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
-
-#[deriving(Eq)]
-pub struct BorrowRecord {
- priv box: *mut raw::Box<()>,
- file: *c_char,
- priv line: size_t
-}
-
-fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
- Local::borrow(|task: &mut Task| task.borrow_list.take())
-}
-
-fn swap_task_borrow_list(f: |~[BorrowRecord]| -> ~[BorrowRecord]) {
- let borrows = match try_take_task_borrow_list() {
- Some(l) => l,
- None => ~[]
- };
- let borrows = f(borrows);
- let borrows = Cell::new(borrows);
- Local::borrow(|task: &mut Task| task.borrow_list = Some(borrows.take()))
-}
-
-pub fn clear_task_borrow_list() {
- // pub because it is used by the box annihilator.
- let _ = try_take_task_borrow_list();
-}
-
-#[cold]
-unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) -> ! {
- debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
-
- match try_take_task_borrow_list() {
- None => { // not recording borrows
- let msg = "borrowed";
- msg.with_c_str(|msg_p| task::begin_unwind_raw(msg_p, file, line))
- }
- Some(borrow_list) => { // recording borrows
- let mut msg = ~"borrowed";
- let mut sep = " at ";
- for entry in borrow_list.rev_iter() {
- if entry.box == box {
- msg.push_str(sep);
- let filename = str::raw::from_c_str(entry.file);
- msg.push_str(filename);
- msg.push_str(format!(":{}", entry.line));
- sep = " and at ";
- }
- }
- msg.with_c_str(|msg_p| task::begin_unwind_raw(msg_p, file, line))
- }
- }
-}
-
-/// Because this code is so perf. sensitive, use a static constant so that
-/// debug printouts are compiled out most of the time.
-static ENABLE_DEBUG: bool = false;
-
-#[inline]
-unsafe fn debug_borrow<T,P:RawPtr<T>>(tag: &'static str,
- p: P,
- old_bits: uint,
- new_bits: uint,
- filename: *c_char,
- line: size_t) {
- //! A useful debugging function that prints a pointer + tag + newline
- //! without allocating memory.
-
- if ENABLE_DEBUG && env::debug_borrow() {
- debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
- }
-
- unsafe fn debug_borrow_slow<T,P:RawPtr<T>>(tag: &'static str,
- p: P,
- old_bits: uint,
- new_bits: uint,
- filename: *c_char,
- line: size_t) {
- let filename = CString::new(filename, false);
- rterrln!("{}{:#x} {:x} {:x} {}:{}",
- tag, p.to_uint(), old_bits, new_bits,
- filename.as_str().unwrap(), line);
- }
-}
-
-#[inline]
-pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
- let a = a as *mut raw::Box<()>;
- let old_ref_count = (*a).ref_count;
- let new_ref_count = old_ref_count | FROZEN_BIT;
-
- debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line);
-
- if (old_ref_count & MUT_BIT) != 0 {
- fail_borrowed(a, file, line);
- }
-
- (*a).ref_count = new_ref_count;
-
- old_ref_count
-}
-
-#[inline]
-pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
- let a = a as *mut raw::Box<()>;
- let old_ref_count = (*a).ref_count;
- let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT;
-
- debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line);
-
- if (old_ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
- fail_borrowed(a, file, line);
- }
-
- (*a).ref_count = new_ref_count;
-
- old_ref_count
-}
-
-pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
- file: *c_char, line: size_t) {
- if (old_ref_count & ALL_BITS) == 0 {
- // was not borrowed before
- let a = a as *mut raw::Box<()>;
- debug_borrow("record_borrow:", a, old_ref_count, 0, file, line);
- swap_task_borrow_list(|borrow_list| {
- let mut borrow_list = borrow_list;
- borrow_list.push(BorrowRecord {box: a, file: file, line: line});
- borrow_list
- })
- }
-}
-
-pub unsafe fn unrecord_borrow(a: *u8,
- old_ref_count: uint,
- file: *c_char,
- line: size_t) {
- if (old_ref_count & ALL_BITS) == 0 {
- // was not borrowed before, so we should find the record at
- // the end of the list
- let a = a as *mut raw::Box<()>;
- debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line);
- swap_task_borrow_list(|borrow_list| {
- let mut borrow_list = borrow_list;
- assert!(!borrow_list.is_empty());
- let br = borrow_list.pop();
- if br.box != a || br.file != file || br.line != line {
- let err = format!("wrong borrow found, br={:?}", br);
- err.with_c_str(|msg_p| {
- task::begin_unwind_raw(msg_p, file, line)
- })
- }
- borrow_list
- })
- }
-}
-
-#[inline]
-pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
- file: *c_char, line: size_t) {
- // Sometimes the box is null, if it is conditionally frozen.
- // See e.g. #4904.
- if !a.is_null() {
- let a = a as *mut raw::Box<()>;
- let old_ref_count = (*a).ref_count;
- let new_ref_count =
- (old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS);
-
- debug_borrow("return_to_mut:",
- a, old_ref_count, new_ref_count, file, line);
-
- (*a).ref_count = new_ref_count;
- }
-}
-
-#[inline]
-pub unsafe fn check_not_borrowed(a: *u8,
- file: *c_char,
- line: size_t) {
- let a = a as *mut raw::Box<()>;
- let ref_count = (*a).ref_count;
- debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line);
- if (ref_count & FROZEN_BIT) != 0 {
- fail_borrowed(a, file, line);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Ports and channels.
-
-use option::*;
-use cast;
-use ops::Drop;
-use rt::kill::BlockedTask;
-use kinds::Send;
-use rt;
-use rt::sched::Scheduler;
-use rt::local::Local;
-use rt::select::{SelectInner, SelectPortInner};
-use select::{Select, SelectPort};
-use unstable::atomics::{AtomicUint, AtomicOption, Acquire, Relaxed, SeqCst};
-use unstable::sync::UnsafeArc;
-use util;
-use util::Void;
-use comm::{GenericChan, GenericSmartChan, GenericPort, Peekable, SendDeferred};
-use cell::{Cell, RefCell};
-use clone::Clone;
-use tuple::ImmutableTuple;
-
-/// A combined refcount / BlockedTask-as-uint pointer.
-///
-/// Can be equal to the following values:
-///
-/// * 2 - both endpoints are alive
-/// * 1 - either the sender or the receiver is dead, determined by context
-/// * <ptr> - A pointer to a blocked Task (see BlockedTask::cast_{to,from}_uint)
-type State = uint;
-
-static STATE_BOTH: State = 2;
-static STATE_ONE: State = 1;
-
-/// The heap-allocated structure shared between two endpoints.
-struct Packet<T> {
- state: AtomicUint,
- payload: Option<T>,
-}
-
-// A one-shot channel.
-pub struct ChanOne<T> {
- priv void_packet: *mut Void,
- priv suppress_finalize: bool
-}
-
-/// A one-shot port.
-pub struct PortOne<T> {
- priv void_packet: *mut Void,
- priv suppress_finalize: bool
-}
-
-pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
- let packet: ~Packet<T> = ~Packet {
- state: AtomicUint::new(STATE_BOTH),
- payload: None
- };
-
- unsafe {
- let packet: *mut Void = cast::transmute(packet);
- let port = PortOne {
- void_packet: packet,
- suppress_finalize: false
- };
- let chan = ChanOne {
- void_packet: packet,
- suppress_finalize: false
- };
- return (port, chan);
- }
-}
-
-impl<T: Send> ChanOne<T> {
- #[inline]
- fn packet(&self) -> *mut Packet<T> {
- unsafe {
- let p: *mut ~Packet<T> = cast::transmute(&self.void_packet);
- let p: *mut Packet<T> = &mut **p;
- return p;
- }
- }
-
- /// Send a message on the one-shot channel. If a receiver task is blocked
- /// waiting for the message, will wake it up and reschedule to it.
- pub fn send(self, val: T) {
- self.try_send(val);
- }
-
- /// As `send`, but also returns whether or not the receiver endpoint is still open.
- pub fn try_send(self, val: T) -> bool {
- self.try_send_inner(val, true)
- }
-
- /// Send a message without immediately rescheduling to a blocked receiver.
- /// This can be useful in contexts where rescheduling is forbidden, or to
- /// optimize for when the sender expects to still have useful work to do.
- pub fn send_deferred(self, val: T) {
- self.try_send_deferred(val);
- }
-
- /// As `send_deferred` and `try_send` together.
- pub fn try_send_deferred(self, val: T) -> bool {
- self.try_send_inner(val, false)
- }
-
- // 'do_resched' configures whether the scheduler immediately switches to
- // the receiving task, or leaves the sending task still running.
- fn try_send_inner(mut self, val: T, do_resched: bool) -> bool {
- if do_resched {
- rtassert!(!rt::in_sched_context());
- }
-
- // In order to prevent starvation of other tasks in situations
- // where a task sends repeatedly without ever receiving, we
- // occassionally yield instead of doing a send immediately.
- // Only doing this if we're doing a rescheduling send,
- // otherwise the caller is expecting not to context switch.
- if do_resched {
- // XXX: This TLS hit should be combined with other uses of the scheduler below
- let sched: ~Scheduler = Local::take();
- sched.maybe_yield();
- }
-
- let mut recvr_active = true;
- let packet = self.packet();
-
- unsafe {
-
- // Install the payload
- rtassert!((*packet).payload.is_none());
- (*packet).payload = Some(val);
-
- // Atomically swap out the old state to figure out what
- // the port's up to, issuing a release barrier to prevent
- // reordering of the payload write. This also issues an
- // acquire barrier that keeps the subsequent access of the
- // ~Task pointer from being reordered.
- let oldstate = (*packet).state.swap(STATE_ONE, SeqCst);
-
- // Suppress the synchronizing actions in the finalizer. We're
- // done with the packet. NB: In case of do_resched, this *must*
- // happen before waking up a blocked task (or be unkillable),
- // because we might get a kill signal during the reschedule.
- self.suppress_finalize = true;
-
- match oldstate {
- STATE_BOTH => {
- // Port is not waiting yet. Nothing to do
- }
- STATE_ONE => {
- // Port has closed. Need to clean up.
- let _packet: ~Packet<T> = cast::transmute(self.void_packet);
- recvr_active = false;
- }
- task_as_state => {
- // Port is blocked. Wake it up.
- let recvr = BlockedTask::cast_from_uint(task_as_state);
- if do_resched {
- recvr.wake().map(|woken_task| {
- Scheduler::run_task(woken_task);
- });
- } else {
- let recvr = Cell::new(recvr);
- Local::borrow(|sched: &mut Scheduler| {
- sched.enqueue_blocked_task(recvr.take());
- })
- }
- }
- }
- }
-
- return recvr_active;
- }
-}
-
-impl<T: Send> PortOne<T> {
- fn packet(&self) -> *mut Packet<T> {
- unsafe {
- let p: *mut ~Packet<T> = cast::transmute(&self.void_packet);
- let p: *mut Packet<T> = &mut **p;
- return p;
- }
- }
-
- /// Wait for a message on the one-shot port. Fails if the send end is closed.
- pub fn recv(self) -> T {
- match self.try_recv() {
- Some(val) => val,
- None => {
- fail!("receiving on closed channel");
- }
- }
- }
-
- /// As `recv`, but returns `None` if the send end is closed rather than failing.
- pub fn try_recv(mut self) -> Option<T> {
- // Optimistic check. If data was sent already, we don't even need to block.
- // No release barrier needed here; we're not handing off our task pointer yet.
- if !self.optimistic_check() {
- // No data available yet.
- // Switch to the scheduler to put the ~Task into the Packet state.
- let sched: ~Scheduler = Local::take();
- sched.deschedule_running_task_and_then(|sched, task| {
- self.block_on(sched, task);
- })
- }
-
- // Task resumes.
- self.recv_ready()
- }
-}
-
-impl<T: Send> SelectInner for PortOne<T> {
- #[inline] #[cfg(not(test))]
- fn optimistic_check(&mut self) -> bool {
- unsafe { (*self.packet()).state.load(Acquire) == STATE_ONE }
- }
-
- #[inline] #[cfg(test)]
- fn optimistic_check(&mut self) -> bool {
- // The optimistic check is never necessary for correctness. For testing
- // purposes, making it randomly return false simulates a racing sender.
- use rand::{Rand};
- let actually_check = Local::borrow(|sched: &mut Scheduler| {
- Rand::rand(&mut sched.rng)
- });
- if actually_check {
- unsafe { (*self.packet()).state.load(Acquire) == STATE_ONE }
- } else {
- false
- }
- }
-
- fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
- unsafe {
- // Atomically swap the task pointer into the Packet state, issuing
- // an acquire barrier to prevent reordering of the subsequent read
- // of the payload. Also issues a release barrier to prevent
- // reordering of any previous writes to the task structure.
- let task_as_state = task.cast_to_uint();
- let oldstate = (*self.packet()).state.swap(task_as_state, SeqCst);
- match oldstate {
- STATE_BOTH => {
- // Data has not been sent. Now we're blocked.
- rtdebug!("non-rendezvous recv");
- false
- }
- STATE_ONE => {
- // Re-record that we are the only owner of the packet.
- // No barrier needed, even if the task gets reawoken
- // on a different core -- this is analogous to writing a
- // payload; a barrier in enqueueing the task protects it.
- // NB(#8132). This *must* occur before the enqueue below.
- // FIXME(#6842, #8130) This is usually only needed for the
- // assertion in recv_ready, except in the case of select().
- // This won't actually ever have cacheline contention, but
- // maybe should be optimized out with a cfg(test) anyway?
- (*self.packet()).state.store(STATE_ONE, Relaxed);
-
- rtdebug!("rendezvous recv");
-
- // Channel is closed. Switch back and check the data.
- // NB: We have to drop back into the scheduler event loop here
- // instead of switching immediately back or we could end up
- // triggering infinite recursion on the scheduler's stack.
- let recvr = BlockedTask::cast_from_uint(task_as_state);
- sched.enqueue_blocked_task(recvr);
- true
- }
- _ => rtabort!("can't block_on; a task is already blocked")
- }
- }
- }
-
- // This is the only select trait function that's not also used in recv.
- fn unblock_from(&mut self) -> bool {
- let packet = self.packet();
- unsafe {
- // In case the data is available, the acquire barrier here matches
- // the release barrier the sender used to release the payload.
- match (*packet).state.load(Acquire) {
- // Impossible. We removed STATE_BOTH when blocking on it, and
- // no self-respecting sender would put it back.
- STATE_BOTH => rtabort!("refcount already 2 in unblock_from"),
- // Here, a sender already tried to wake us up. Perhaps they
- // even succeeded! Data is available.
- STATE_ONE => true,
- // Still registered as blocked. Need to "unblock" the pointer.
- task_as_state => {
- // In the window between the load and the CAS, a sender
- // might take the pointer and set the refcount to ONE. If
- // that happens, we shouldn't clobber that with BOTH!
- // Acquire barrier again for the same reason as above.
- match (*packet).state.compare_and_swap(task_as_state, STATE_BOTH,
- Acquire) {
- STATE_BOTH => rtabort!("refcount became 2 in unblock_from"),
- STATE_ONE => true, // Lost the race. Data available.
- same_ptr => {
- // We successfully unblocked our task pointer.
- rtassert!(task_as_state == same_ptr);
- let handle = BlockedTask::cast_from_uint(task_as_state);
- // Because we are already awake, the handle we
- // gave to this port shall already be empty.
- handle.assert_already_awake();
- false
- }
- }
- }
- }
- }
- }
-}
-
-impl<T: Send> Select for PortOne<T> { }
-
-impl<T: Send> SelectPortInner<T> for PortOne<T> {
- fn recv_ready(mut self) -> Option<T> {
- let packet = self.packet();
-
- // No further memory barrier is needed here to access the
- // payload. Some scenarios:
- //
- // 1) We encountered STATE_ONE above - the atomic_xchg was the acq barrier. We're fine.
- // 2) We encountered STATE_BOTH above and blocked. The sending task then ran us
- // and ran on its thread. The sending task issued a read barrier when taking the
- // pointer to the receiving task.
- // 3) We encountered STATE_BOTH above and blocked, but the receiving task (this task)
- // is pinned to some other scheduler, so the sending task had to give us to
- // a different scheduler for resuming. That send synchronized memory.
- unsafe {
- // See corresponding store() above in block_on for rationale.
- // FIXME(#8130) This can happen only in test builds.
- // This load is not required for correctness and may be compiled out.
- rtassert!((*packet).state.load(Relaxed) == STATE_ONE);
-
- let payload = (*packet).payload.take();
-
- // The sender has closed up shop. Drop the packet.
- let _packet: ~Packet<T> = cast::transmute(self.void_packet);
- // Suppress the synchronizing actions in the finalizer. We're done with the packet.
- self.suppress_finalize = true;
- return payload;
- }
- }
-}
-
-impl<T: Send> SelectPort<T> for PortOne<T> { }
-
-impl<T: Send> Peekable<T> for PortOne<T> {
- fn peek(&self) -> bool {
- unsafe {
- let packet: *mut Packet<T> = self.packet();
- let oldstate = (*packet).state.load(SeqCst);
- match oldstate {
- STATE_BOTH => false,
- STATE_ONE => (*packet).payload.is_some(),
- _ => rtabort!("peeked on a blocked task")
- }
- }
- }
-}
-
-#[unsafe_destructor]
-impl<T: Send> Drop for ChanOne<T> {
- fn drop(&mut self) {
- if self.suppress_finalize { return }
-
- unsafe {
- let oldstate = (*self.packet()).state.swap(STATE_ONE, SeqCst);
- match oldstate {
- STATE_BOTH => {
- // Port still active. It will destroy the Packet.
- },
- STATE_ONE => {
- let _packet: ~Packet<T> = cast::transmute(self.void_packet);
- },
- task_as_state => {
- // The port is blocked waiting for a message we will never send. Wake it.
- rtassert!((*self.packet()).payload.is_none());
- let recvr = BlockedTask::cast_from_uint(task_as_state);
- recvr.wake().map(|woken_task| {
- Scheduler::run_task(woken_task);
- });
- }
- }
- }
- }
-}
-
-#[unsafe_destructor]
-impl<T: Send> Drop for PortOne<T> {
- fn drop(&mut self) {
- if self.suppress_finalize { return }
-
- unsafe {
- let oldstate = (*self.packet()).state.swap(STATE_ONE, SeqCst);
- match oldstate {
- STATE_BOTH => {
- // Chan still active. It will destroy the packet.
- },
- STATE_ONE => {
- let _packet: ~Packet<T> = cast::transmute(self.void_packet);
- }
- task_as_state => {
- // This case occurs during unwinding, when the blocked
- // receiver was killed awake. The task can't still be
- // blocked (we are it), but we need to free the handle.
- let recvr = BlockedTask::cast_from_uint(task_as_state);
- recvr.assert_already_awake();
- }
- }
- }
- }
-}
-
-struct StreamPayload<T> {
- val: T,
- next: PortOne<StreamPayload<T>>
-}
-
-type StreamChanOne<T> = ChanOne<StreamPayload<T>>;
-type StreamPortOne<T> = PortOne<StreamPayload<T>>;
-
-/// A channel with unbounded size.
-pub struct Chan<T> {
- // FIXME #5372. Using RefCell because we don't take &mut self
- next: RefCell<StreamChanOne<T>>
-}
-
-/// An port with unbounded size.
-pub struct Port<T> {
- // FIXME #5372. Using RefCell because we don't take &mut self
- next: RefCell<Option<StreamPortOne<T>>>
-}
-
-pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
- let (pone, cone) = oneshot();
- let port = Port { next: RefCell::new(Some(pone)) };
- let chan = Chan { next: RefCell::new(cone) };
- return (port, chan);
-}
-
-impl<T: Send> Chan<T> {
- fn try_send_inner(&self, val: T, do_resched: bool) -> bool {
- let (next_pone, mut cone) = oneshot();
- let mut b = self.next.borrow_mut();
- util::swap(&mut cone, b.get());
- cone.try_send_inner(StreamPayload { val: val, next: next_pone }, do_resched)
- }
-}
-
-impl<T: Send> GenericChan<T> for Chan<T> {
- fn send(&self, val: T) {
- self.try_send(val);
- }
-}
-
-impl<T: Send> GenericSmartChan<T> for Chan<T> {
- fn try_send(&self, val: T) -> bool {
- self.try_send_inner(val, true)
- }
-}
-
-impl<T: Send> SendDeferred<T> for Chan<T> {
- fn send_deferred(&self, val: T) {
- self.try_send_deferred(val);
- }
- fn try_send_deferred(&self, val: T) -> bool {
- self.try_send_inner(val, false)
- }
-}
-
-impl<T: Send> GenericPort<T> for Port<T> {
- fn recv(&self) -> T {
- match self.try_recv() {
- Some(val) => val,
- None => {
- fail!("receiving on closed channel");
- }
- }
- }
-
- fn try_recv(&self) -> Option<T> {
- let mut b = self.next.borrow_mut();
- b.get().take().map_default(None, |pone| {
- match pone.try_recv() {
- Some(StreamPayload { val, next }) => {
- *b.get() = Some(next);
- Some(val)
- }
- None => None
- }
- })
- }
-}
-
-impl<T: Send> Peekable<T> for Port<T> {
- fn peek(&self) -> bool {
- self.next.with_mut(|p| p.get_mut_ref().peek())
- }
-}
-
-// XXX: Kind of gross. A Port<T> should be selectable so you can make an array
-// of them, but a &Port<T> should also be selectable so you can select2 on it
-// alongside a PortOne<U> without passing the port by value in recv_ready.
-
-impl<'self, T: Send> SelectInner for &'self Port<T> {
- #[inline]
- fn optimistic_check(&mut self) -> bool {
- self.next.with_mut(|pone| { pone.get_mut_ref().optimistic_check() })
- }
-
- #[inline]
- fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
- let mut b = self.next.borrow_mut();
- b.get().get_mut_ref().block_on(sched, task)
- }
-
- #[inline]
- fn unblock_from(&mut self) -> bool {
- self.next.with_mut(|pone| { pone.get_mut_ref().unblock_from() })
- }
-}
-
-impl<'self, T: Send> Select for &'self Port<T> { }
-
-impl<T: Send> SelectInner for Port<T> {
- #[inline]
- fn optimistic_check(&mut self) -> bool {
- (&*self).optimistic_check()
- }
-
- #[inline]
- fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
- (&*self).block_on(sched, task)
- }
-
- #[inline]
- fn unblock_from(&mut self) -> bool {
- (&*self).unblock_from()
- }
-}
-
-impl<T: Send> Select for Port<T> { }
-
-impl<'self, T: Send> SelectPortInner<T> for &'self Port<T> {
- fn recv_ready(self) -> Option<T> {
- let mut b = self.next.borrow_mut();
- match b.get().take_unwrap().recv_ready() {
- Some(StreamPayload { val, next }) => {
- *b.get() = Some(next);
- Some(val)
- }
- None => None
- }
- }
-}
-
-impl<'self, T: Send> SelectPort<T> for &'self Port<T> { }
-
-pub struct SharedChan<T> {
- // Just like Chan, but a shared AtomicOption instead of Cell
- priv next: UnsafeArc<AtomicOption<StreamChanOne<T>>>
-}
-
-impl<T: Send> SharedChan<T> {
- pub fn new(chan: Chan<T>) -> SharedChan<T> {
- let next = chan.next.unwrap();
- let next = AtomicOption::new(~next);
- SharedChan { next: UnsafeArc::new(next) }
- }
-}
-
-impl<T: Send> SharedChan<T> {
- fn try_send_inner(&self, val: T, do_resched: bool) -> bool {
- unsafe {
- let (next_pone, next_cone) = oneshot();
- let cone = (*self.next.get()).swap(~next_cone, SeqCst);
- cone.unwrap().try_send_inner(StreamPayload { val: val, next: next_pone },
- do_resched)
- }
- }
-}
-
-impl<T: Send> GenericChan<T> for SharedChan<T> {
- fn send(&self, val: T) {
- self.try_send(val);
- }
-}
-
-impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
- fn try_send(&self, val: T) -> bool {
- self.try_send_inner(val, true)
- }
-}
-
-impl<T: Send> SendDeferred<T> for SharedChan<T> {
- fn send_deferred(&self, val: T) {
- self.try_send_deferred(val);
- }
- fn try_send_deferred(&self, val: T) -> bool {
- self.try_send_inner(val, false)
- }
-}
-
-impl<T: Send> Clone for SharedChan<T> {
- fn clone(&self) -> SharedChan<T> {
- SharedChan {
- next: self.next.clone()
- }
- }
-}
-
-pub struct SharedPort<T> {
- // The next port on which we will receive the next port on which we will receive T
- priv next_link: UnsafeArc<AtomicOption<PortOne<StreamPortOne<T>>>>
-}
-
-impl<T: Send> SharedPort<T> {
- pub fn new(port: Port<T>) -> SharedPort<T> {
- // Put the data port into a new link pipe
- let next_data_port = port.next.unwrap().unwrap();
- let (next_link_port, next_link_chan) = oneshot();
- next_link_chan.send(next_data_port);
- let next_link = AtomicOption::new(~next_link_port);
- SharedPort { next_link: UnsafeArc::new(next_link) }
- }
-}
-
-impl<T: Send> GenericPort<T> for SharedPort<T> {
- fn recv(&self) -> T {
- match self.try_recv() {
- Some(val) => val,
- None => {
- fail!("receiving on a closed channel");
- }
- }
- }
-
- fn try_recv(&self) -> Option<T> {
- unsafe {
- let (next_link_port, next_link_chan) = oneshot();
- let link_port = (*self.next_link.get()).swap(~next_link_port, SeqCst);
- let link_port = link_port.unwrap();
- let data_port = link_port.recv();
- let (next_data_port, res) = match data_port.try_recv() {
- Some(StreamPayload { val, next }) => {
- (next, Some(val))
- }
- None => {
- let (next_data_port, _) = oneshot();
- (next_data_port, None)
- }
- };
- next_link_chan.send(next_data_port);
- return res;
- }
- }
-}
-
-impl<T: Send> Clone for SharedPort<T> {
- fn clone(&self) -> SharedPort<T> {
- SharedPort {
- next_link: self.next_link.clone()
- }
- }
-}
-
-// FIXME #7760: Need better name
-type MegaPipe<T> = (SharedPort<T>, SharedChan<T>);
-
-pub fn megapipe<T: Send>() -> MegaPipe<T> {
- let (port, chan) = stream();
- (SharedPort::new(port), SharedChan::new(chan))
-}
-
-impl<T: Send> GenericChan<T> for MegaPipe<T> {
- fn send(&self, val: T) {
- self.second_ref().send(val)
- }
-}
-
-impl<T: Send> GenericSmartChan<T> for MegaPipe<T> {
- fn try_send(&self, val: T) -> bool {
- self.second_ref().try_send(val)
- }
-}
-
-impl<T: Send> GenericPort<T> for MegaPipe<T> {
- fn recv(&self) -> T {
- self.first_ref().recv()
- }
-
- fn try_recv(&self) -> Option<T> {
- self.first_ref().try_recv()
- }
-}
-
-impl<T: Send> SendDeferred<T> for MegaPipe<T> {
- fn send_deferred(&self, val: T) {
- self.second_ref().send_deferred(val)
- }
- fn try_send_deferred(&self, val: T) -> bool {
- self.second_ref().try_send_deferred(val)
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use option::*;
- use rt::test::*;
- use cell::Cell;
- use num::Times;
- use rt::util;
-
- #[test]
- fn oneshot_single_thread_close_port_first() {
- // Simple test of closing without sending
- do run_in_newsched_task {
- let (port, _chan) = oneshot::<int>();
- { let _p = port; }
- }
- }
-
- #[test]
- fn oneshot_single_thread_close_chan_first() {
- // Simple test of closing without sending
- do run_in_newsched_task {
- let (_port, chan) = oneshot::<int>();
- { let _c = chan; }
- }
- }
-
- #[test]
- fn oneshot_single_thread_send_port_close() {
- // Testing that the sender cleans up the payload if receiver is closed
- do run_in_newsched_task {
- let (port, chan) = oneshot::<~int>();
- { let _p = port; }
- chan.send(~0);
- }
- }
-
- #[test]
- fn oneshot_single_thread_recv_chan_close() {
- // Receiving on a closed chan will fail
- do run_in_newsched_task {
- let res = do spawntask_try {
- let (port, chan) = oneshot::<~int>();
- { let _c = chan; }
- port.recv();
- };
- // What is our res?
- rtdebug!("res is: {:?}", res.is_err());
- assert!(res.is_err());
- }
- }
-
- #[test]
- fn oneshot_single_thread_send_then_recv() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<~int>();
- chan.send(~10);
- assert!(port.recv() == ~10);
- }
- }
-
- #[test]
- fn oneshot_single_thread_try_send_open() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- assert!(chan.try_send(10));
- assert!(port.recv() == 10);
- }
- }
-
- #[test]
- fn oneshot_single_thread_try_send_closed() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- { let _p = port; }
- assert!(!chan.try_send(10));
- }
- }
-
- #[test]
- fn oneshot_single_thread_try_recv_open() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- chan.send(10);
- assert!(port.try_recv() == Some(10));
- }
- }
-
- #[test]
- fn oneshot_single_thread_try_recv_closed() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- { let _c = chan; }
- assert!(port.try_recv() == None);
- }
- }
-
- #[test]
- fn oneshot_single_thread_peek_data() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- assert!(!port.peek());
- chan.send(10);
- assert!(port.peek());
- }
- }
-
- #[test]
- fn oneshot_single_thread_peek_close() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- { let _c = chan; }
- assert!(!port.peek());
- assert!(!port.peek());
- }
- }
-
- #[test]
- fn oneshot_single_thread_peek_open() {
- do run_in_newsched_task {
- let (port, _) = oneshot::<int>();
- assert!(!port.peek());
- }
- }
-
- #[test]
- fn oneshot_multi_task_recv_then_send() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<~int>();
- let port_cell = Cell::new(port);
- do spawntask {
- assert!(port_cell.take().recv() == ~10);
- }
-
- chan.send(~10);
- }
- }
-
- #[test]
- fn oneshot_multi_task_recv_then_close() {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<~int>();
- let port_cell = Cell::new(port);
- let chan_cell = Cell::new(chan);
- do spawntask_later {
- let _cell = chan_cell.take();
- }
- let res = do spawntask_try {
- assert!(port_cell.take().recv() == ~10);
- };
- assert!(res.is_err());
- }
- }
-
- #[test]
- fn oneshot_multi_thread_close_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- stress_factor().times(|| {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- let port_cell = Cell::new(port);
- let thread = do spawntask_thread {
- let _p = port_cell.take();
- };
- let _chan = chan;
- thread.join();
- }
- })
- }
-
- #[test]
- fn oneshot_multi_thread_send_close_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- stress_factor().times(|| {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- let chan_cell = Cell::new(chan);
- let port_cell = Cell::new(port);
- let thread1 = do spawntask_thread {
- let _p = port_cell.take();
- };
- let thread2 = do spawntask_thread {
- let c = chan_cell.take();
- c.send(1);
- };
- thread1.join();
- thread2.join();
- }
- })
- }
-
- #[test]
- fn oneshot_multi_thread_recv_close_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- stress_factor().times(|| {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<int>();
- let chan_cell = Cell::new(chan);
- let port_cell = Cell::new(port);
- let thread1 = do spawntask_thread {
- let port_cell = Cell::new(port_cell.take());
- let res = do spawntask_try {
- port_cell.take().recv();
- };
- assert!(res.is_err());
- };
- let thread2 = do spawntask_thread {
- let chan_cell = Cell::new(chan_cell.take());
- do spawntask {
- chan_cell.take();
- }
- };
- thread1.join();
- thread2.join();
- }
- })
- }
-
- #[test]
- fn oneshot_multi_thread_send_recv_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- stress_factor().times(|| {
- do run_in_newsched_task {
- let (port, chan) = oneshot::<~int>();
- let chan_cell = Cell::new(chan);
- let port_cell = Cell::new(port);
- let thread1 = do spawntask_thread {
- chan_cell.take().send(~10);
- };
- let thread2 = do spawntask_thread {
- assert!(port_cell.take().recv() == ~10);
- };
- thread1.join();
- thread2.join();
- }
- })
- }
-
- #[test]
- fn stream_send_recv_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- stress_factor().times(|| {
- do run_in_mt_newsched_task {
- let (port, chan) = stream::<~int>();
-
- send(chan, 0);
- recv(port, 0);
-
- fn send(chan: Chan<~int>, i: int) {
- if i == 10 { return }
-
- let chan_cell = Cell::new(chan);
- do spawntask_random {
- let chan = chan_cell.take();
- chan.send(~i);
- send(chan, i + 1);
- }
- }
-
- fn recv(port: Port<~int>, i: int) {
- if i == 10 { return }
-
- let port_cell = Cell::new(port);
- do spawntask_random {
- let port = port_cell.take();
- assert!(port.recv() == ~i);
- recv(port, i + 1);
- };
- }
- }
- })
- }
-
- #[test]
- fn recv_a_lot() {
- // Regression test that we don't run out of stack in scheduler context
- do run_in_newsched_task {
- let (port, chan) = stream();
- 10000.times(|| { chan.send(()) });
- 10000.times(|| { port.recv() });
- }
- }
-
- #[test]
- fn shared_chan_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- do run_in_mt_newsched_task {
- let (port, chan) = stream();
- let chan = SharedChan::new(chan);
- let total = stress_factor() + 100;
- total.times(|| {
- let chan_clone = chan.clone();
- do spawntask_random {
- chan_clone.send(());
- }
- });
-
- total.times(|| {
- port.recv();
- });
- }
- }
-
- #[test]
- fn shared_port_stress() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- do run_in_mt_newsched_task {
- let (end_port, end_chan) = stream();
- let (port, chan) = stream();
- let end_chan = SharedChan::new(end_chan);
- let port = SharedPort::new(port);
- let total = stress_factor() + 100;
- total.times(|| {
- let end_chan_clone = end_chan.clone();
- let port_clone = port.clone();
- do spawntask_random {
- port_clone.recv();
- end_chan_clone.send(());
- }
- });
-
- total.times(|| {
- chan.send(());
- });
-
- total.times(|| {
- end_port.recv();
- });
- }
- }
-
- #[test]
- fn shared_port_close_simple() {
- do run_in_mt_newsched_task {
- let (port, chan) = stream::<()>();
- let port = SharedPort::new(port);
- { let _chan = chan; }
- assert!(port.try_recv().is_none());
- }
- }
-
- #[test]
- fn shared_port_close() {
- do run_in_mt_newsched_task {
- let (end_port, end_chan) = stream::<bool>();
- let (port, chan) = stream::<()>();
- let end_chan = SharedChan::new(end_chan);
- let port = SharedPort::new(port);
- let chan = SharedChan::new(chan);
- let send_total = 10;
- let recv_total = 20;
- do spawntask_random {
- send_total.times(|| {
- let chan_clone = chan.clone();
- do spawntask_random {
- chan_clone.send(());
- }
- });
- }
- let end_chan_clone = end_chan.clone();
- do spawntask_random {
- recv_total.times(|| {
- let port_clone = port.clone();
- let end_chan_clone = end_chan_clone.clone();
- do spawntask_random {
- let recvd = port_clone.try_recv().is_some();
- end_chan_clone.send(recvd);
- }
- });
- }
-
- let mut recvd = 0;
- recv_total.times(|| {
- recvd += if end_port.recv() { 1 } else { 0 };
- });
-
- assert!(recvd == send_total);
- }
- }
-
- #[test]
- fn megapipe_stress() {
- use rand;
- use rand::Rng;
-
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
-
- do run_in_mt_newsched_task {
- let (end_port, end_chan) = stream::<()>();
- let end_chan = SharedChan::new(end_chan);
- let pipe = megapipe();
- let total = stress_factor() + 10;
- let mut rng = rand::rng();
- total.times(|| {
- let msgs = rng.gen_range(0u, 10);
- let pipe_clone = pipe.clone();
- let end_chan_clone = end_chan.clone();
- do spawntask_random {
- msgs.times(|| {
- pipe_clone.send(());
- });
- msgs.times(|| {
- pipe_clone.recv();
- });
- }
-
- end_chan_clone.send(());
- });
-
- total.times(|| {
- end_port.recv();
- });
- }
- }
-
- #[test]
- fn send_deferred() {
- use unstable::sync::atomically;
-
- // Tests no-rescheduling of send_deferred on all types of channels.
- do run_in_newsched_task {
- let (pone, cone) = oneshot();
- let (pstream, cstream) = stream();
- let (pshared, cshared) = stream();
- let cshared = SharedChan::new(cshared);
- let mp = megapipe();
-
- let pone = Cell::new(pone);
- do spawntask { pone.take().recv(); }
- let pstream = Cell::new(pstream);
- do spawntask { pstream.take().recv(); }
- let pshared = Cell::new(pshared);
- do spawntask { pshared.take().recv(); }
- let p_mp = Cell::new(mp.clone());
- do spawntask { p_mp.take().recv(); }
-
- let cs = Cell::new((cone, cstream, cshared, mp));
- unsafe {
- atomically(|| {
- let (cone, cstream, cshared, mp) = cs.take();
- cone.send_deferred(());
- cstream.send_deferred(());
- cshared.send_deferred(());
- mp.send_deferred(());
- })
- }
- }
- }
-
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use option::*;
-use super::stack::StackSegment;
-use libc::c_void;
-use uint;
-use cast::{transmute, transmute_mut_unsafe,
- transmute_region, transmute_mut_region};
-
-pub static RED_ZONE: uint = 20 * 1024;
-
-// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
-// SSE regs. It would be marginally better not to do this. In C++ we
-// use an attribute on a struct.
-// FIXME #7761: It would be nice to define regs as `~Option<Registers>` since
-// the registers are sometimes empty, but the discriminant would
-// then misalign the regs again.
-pub struct Context {
- /// The context entry point, saved here for later destruction
- priv start: Option<~proc()>,
- /// Hold the registers while the task or scheduler is suspended
- priv regs: ~Registers,
- /// Lower bound and upper bound for the stack
- priv stack_bounds: Option<(uint, uint)>,
-}
-
-impl Context {
- pub fn empty() -> Context {
- Context {
- start: None,
- regs: new_regs(),
- stack_bounds: None,
- }
- }
-
- /// Create a new context that will resume execution by running proc()
- pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
- // FIXME #7767: Putting main into a ~ so it's a thin pointer and can
- // be passed to the spawn function. Another unfortunate
- // allocation
- let start = ~start;
-
- // The C-ABI function that is the task entry point
- extern fn task_start_wrapper(f: &proc()) {
- // XXX(pcwalton): This may be sketchy.
- unsafe {
- let f: &|| = transmute(f);
- (*f)()
- }
- }
-
- let fp: *c_void = task_start_wrapper as *c_void;
- let argp: *c_void = unsafe { transmute::<&proc(), *c_void>(&*start) };
- let sp: *uint = stack.end();
- let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };
- // Save and then immediately load the current context,
- // which we will then modify to call the given function when restored
- let mut regs = new_regs();
- unsafe {
- rust_swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs));
- };
-
- initialize_call_frame(&mut *regs, fp, argp, sp);
-
- // Scheduler tasks don't have a stack in the "we allocated it" sense,
- // but rather they run on pthreads stacks. We have complete control over
- // them in terms of the code running on them (and hopefully they don't
- // overflow). Additionally, their coroutine stacks are listed as being
- // zero-length, so that's how we detect what's what here.
- let stack_base: *uint = stack.start();
- let bounds = if sp as uint == stack_base as uint {
- None
- } else {
- Some((stack_base as uint, sp as uint))
- };
- return Context {
- start: Some(start),
- regs: regs,
- stack_bounds: bounds,
- }
- }
-
- /* Switch contexts
-
- Suspend the current execution context and resume another by
- saving the registers values of the executing thread to a Context
- then loading the registers from a previously saved Context.
- */
- pub fn swap(out_context: &mut Context, in_context: &Context) {
- rtdebug!("swapping contexts");
- let out_regs: &mut Registers = match out_context {
- &Context { regs: ~ref mut r, .. } => r
- };
- let in_regs: &Registers = match in_context {
- &Context { regs: ~ref r, .. } => r
- };
-
- rtdebug!("noting the stack limit and doing raw swap");
-
- unsafe {
- // Right before we switch to the new context, set the new context's
- // stack limit in the OS-specified TLS slot. This also means that
- // we cannot call any more rust functions after record_stack_bounds
- // returns because they would all likely fail due to the limit being
- // invalid for the current task. Lucky for us `rust_swap_registers`
- // is a C function so we don't have to worry about that!
- match in_context.stack_bounds {
- Some((lo, hi)) => record_stack_bounds(lo, hi),
- // If we're going back to one of the original contexts or
- // something that's possibly not a "normal task", then reset
- // the stack limit to 0 to make morestack never fail
- None => record_stack_bounds(0, uint::max_value),
- }
- rust_swap_registers(out_regs, in_regs)
- }
- }
-}
-
-extern {
- fn rust_swap_registers(out_regs: *mut Registers, in_regs: *Registers);
-}
-
-// Register contexts used in various architectures
-//
-// These structures all represent a context of one task throughout its
-// execution. Each struct is a representation of the architecture's register
-// set. When swapping between tasks, these register sets are used to save off
-// the current registers into one struct, and load them all from another.
-//
-// Note that this is only used for context switching, which means that some of
-// the registers may go unused. For example, for architectures with
-// callee/caller saved registers, the context will only reflect the callee-saved
-// registers. This is because the caller saved registers are already stored
-// elsewhere on the stack (if it was necessary anyway).
-//
-// Additionally, there may be fields on various architectures which are unused
-// entirely because they only reflect what is theoretically possible for a
-// "complete register set" to show, but user-space cannot alter these registers.
-// An example of this would be the segment selectors for x86.
-//
-// These structures/functions are roughly in-sync with the source files inside
-// of src/rt/arch/$arch. The only currently used function from those folders is
-// the `rust_swap_registers` function, but that's only because for now segmented
-// stacks are disabled.
-
-#[cfg(target_arch = "x86")]
-struct Registers {
- eax: u32, ebx: u32, ecx: u32, edx: u32,
- ebp: u32, esi: u32, edi: u32, esp: u32,
- cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
- eflags: u32, eip: u32
-}
-
-#[cfg(target_arch = "x86")]
-fn new_regs() -> ~Registers {
- ~Registers {
- eax: 0, ebx: 0, ecx: 0, edx: 0,
- ebp: 0, esi: 0, edi: 0, esp: 0,
- cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
- eflags: 0, eip: 0
- }
-}
-
-#[cfg(target_arch = "x86")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
- sp: *mut uint) {
-
- let sp = align_down(sp);
- let sp = mut_offset(sp, -4);
-
- unsafe { *sp = arg as uint };
- let sp = mut_offset(sp, -1);
- unsafe { *sp = 0 }; // The final return address
-
- regs.esp = sp as u32;
- regs.eip = fptr as u32;
-
- // Last base pointer on the stack is 0
- regs.ebp = 0;
-}
-
-// windows requires saving more registers (both general and XMM), so the windows
-// register context must be larger.
-#[cfg(windows, target_arch = "x86_64")]
-type Registers = [uint, ..34];
-#[cfg(not(windows), target_arch = "x86_64")]
-type Registers = [uint, ..22];
-
-#[cfg(windows, target_arch = "x86_64")]
-fn new_regs() -> ~Registers { ~([0, .. 34]) }
-#[cfg(not(windows), target_arch = "x86_64")]
-fn new_regs() -> ~Registers { ~([0, .. 22]) }
-
-#[cfg(target_arch = "x86_64")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
- sp: *mut uint) {
-
- // Redefinitions from rt/arch/x86_64/regs.h
- static RUSTRT_ARG0: uint = 3;
- static RUSTRT_RSP: uint = 1;
- static RUSTRT_IP: uint = 8;
- static RUSTRT_RBP: uint = 2;
-
- let sp = align_down(sp);
- let sp = mut_offset(sp, -1);
-
- // The final return address. 0 indicates the bottom of the stack
- unsafe { *sp = 0; }
-
- rtdebug!("creating call frame");
- rtdebug!("fptr {}", fptr);
- rtdebug!("arg {}", arg);
- rtdebug!("sp {}", sp);
-
- regs[RUSTRT_ARG0] = arg as uint;
- regs[RUSTRT_RSP] = sp as uint;
- regs[RUSTRT_IP] = fptr as uint;
-
- // Last base pointer on the stack should be 0
- regs[RUSTRT_RBP] = 0;
-}
-
-#[cfg(target_arch = "arm")]
-type Registers = [uint, ..32];
-
-#[cfg(target_arch = "arm")]
-fn new_regs() -> ~Registers { ~([0, .. 32]) }
-
-#[cfg(target_arch = "arm")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
- sp: *mut uint) {
- let sp = align_down(sp);
- // sp of arm eabi is 8-byte aligned
- let sp = mut_offset(sp, -2);
-
- // The final return address. 0 indicates the bottom of the stack
- unsafe { *sp = 0; }
-
- regs[0] = arg as uint; // r0
- regs[13] = sp as uint; // #53 sp, r13
- regs[14] = fptr as uint; // #60 pc, r15 --> lr
-}
-
-#[cfg(target_arch = "mips")]
-type Registers = [uint, ..32];
-
-#[cfg(target_arch = "mips")]
-fn new_regs() -> ~Registers { ~([0, .. 32]) }
-
-#[cfg(target_arch = "mips")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
- sp: *mut uint) {
- let sp = align_down(sp);
- // sp of mips o32 is 8-byte aligned
- let sp = mut_offset(sp, -2);
-
- // The final return address. 0 indicates the bottom of the stack
- unsafe { *sp = 0; }
-
- regs[4] = arg as uint;
- regs[29] = sp as uint;
- regs[25] = fptr as uint;
- regs[31] = fptr as uint;
-}
-
-fn align_down(sp: *mut uint) -> *mut uint {
- unsafe {
- let sp: uint = transmute(sp);
- let sp = sp & !(16 - 1);
- transmute::<uint, *mut uint>(sp)
- }
-}
-
-// ptr::mut_offset is positive ints only
-#[inline]
-pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
- use mem::size_of;
- (ptr as int + count * (size_of::<T>() as int)) as *mut T
-}
-
-#[inline(always)]
-pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
- // When the old runtime had segmented stacks, it used a calculation that was
- // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
- // symbol resolution, llvm function calls, etc. In theory this red zone
- // value is 0, but it matters far less when we have gigantic stacks because
- // we don't need to be so exact about our stack budget. The "fudge factor"
- // was because LLVM doesn't emit a stack check for functions < 256 bytes in
- // size. Again though, we have giant stacks, so we round all these
- // calculations up to the nice round number of 20k.
- record_sp_limit(stack_lo + RED_ZONE);
-
- return target_record_stack_bounds(stack_lo, stack_hi);
-
- #[cfg(not(windows))] #[cfg(not(target_arch = "x86_64"))] #[inline(always)]
- unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
- #[cfg(windows, target_arch = "x86_64")] #[inline(always)]
- unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
- // Windows compiles C functions which may check the stack bounds. This
- // means that if we want to perform valid FFI on windows, then we need
- // to ensure that the stack bounds are what they truly are for this
- // task. More info can be found at:
- // https://github.com/mozilla/rust/issues/3445#issuecomment-26114839
- //
- // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
- asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
- asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");
- }
-}
-
-/// Records the current limit of the stack as specified by `end`.
-///
-/// This is stored in an OS-dependent location, likely inside of the thread
-/// local storage. The location that the limit is stored is a pre-ordained
-/// location because it's where LLVM has emitted code to check.
-///
-/// Note that this cannot be called under normal circumstances. This function is
-/// changing the stack limit, so upon returning any further function calls will
-/// possibly be triggering the morestack logic if you're not careful.
-///
-/// Also note that this and all of the inside functions are all flagged as
-/// "inline(always)" because they're messing around with the stack limits. This
-/// would be unfortunate for the functions themselves to trigger a morestack
-/// invocation (if they were an actual function call).
-#[inline(always)]
-pub unsafe fn record_sp_limit(limit: uint) {
- return target_record_sp_limit(limit);
-
- // x86-64
- #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- asm!("movq $$0x60+90*8, %rsi
- movq $0, %gs:(%rsi)" :: "r"(limit) : "rsi" : "volatile")
- }
- #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile")
- }
- #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
- // store this inside of the "arbitrary data slot", but double the size
- // because this is 64 bit instead of 32 bit
- asm!("movq $0, %gs:0x28" :: "r"(limit) :: "volatile")
- }
- #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- asm!("movq $0, %fs:24" :: "r"(limit) :: "volatile")
- }
-
- // x86
- #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- asm!("movl $$0x48+90*4, %eax
- movl $0, %gs:(%eax)" :: "r"(limit) : "eax" : "volatile")
- }
- #[cfg(target_arch = "x86", target_os = "linux")]
- #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile")
- }
- #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
- // store this inside of the "arbitrary data slot"
- asm!("movl $0, %fs:0x14" :: "r"(limit) :: "volatile")
- }
-
- // mips, arm - Some brave soul can port these to inline asm, but it's over
- // my head personally
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "arm")] #[inline(always)]
- unsafe fn target_record_sp_limit(limit: uint) {
- return record_sp_limit(limit as *c_void);
- extern {
- fn record_sp_limit(limit: *c_void);
- }
- }
-}
-
-/// The counterpart of the function above, this function will fetch the current
-/// stack limit stored in TLS.
-///
-/// Note that all of these functions are meant to be exact counterparts of their
-/// brethren above, except that the operands are reversed.
-///
-/// As with the setter, this function does not have a __morestack header and can
-/// therefore be called in a "we're out of stack" situation.
-#[inline(always)]
-pub unsafe fn get_sp_limit() -> uint {
- return target_get_sp_limit();
-
- // x86-64
- #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movq $$0x60+90*8, %rsi
- movq %gs:(%rsi), $0" : "=r"(limit) :: "rsi" : "volatile");
- return limit;
- }
- #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movq %fs:112, $0" : "=r"(limit) ::: "volatile");
- return limit;
- }
- #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile");
- return limit;
- }
- #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movq %fs:24, $0" : "=r"(limit) ::: "volatile");
- return limit;
- }
-
- // x86
- #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movl $$0x48+90*4, %eax
- movl %gs:(%eax), $0" : "=r"(limit) :: "eax" : "volatile");
- return limit;
- }
- #[cfg(target_arch = "x86", target_os = "linux")]
- #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movl %gs:48, $0" : "=r"(limit) ::: "volatile");
- return limit;
- }
- #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- let limit;
- asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile");
- return limit;
- }
-
- // mips, arm - Some brave soul can port these to inline asm, but it's over
- // my head personally
- #[cfg(target_arch = "mips")]
- #[cfg(target_arch = "arm")] #[inline(always)]
- unsafe fn target_get_sp_limit() -> uint {
- return get_sp_limit() as uint;
- extern {
- fn get_sp_limit() -> *c_void;
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::MutableSet;
-use hashmap::HashSet;
-use option::{Some, None, Option};
-use vec::ImmutableVector;
-use rt::rtio::EventLoop;
-
-// Need to tell the linker on OS X to not barf on undefined symbols
-// and instead look them up at runtime, which we need to resolve
-// the crate_map properly.
-#[cfg(target_os = "macos")]
-#[link_args = "-Wl,-U,__rust_crate_map_toplevel"]
-extern {}
-
-pub struct ModEntry<'self> {
- name: &'self str,
- log_level: *mut u32
-}
-
-pub struct CrateMap<'self> {
- version: i32,
- entries: &'self [ModEntry<'self>],
- children: &'self [&'self CrateMap<'self>],
- event_loop_factory: Option<extern "C" fn() -> ~EventLoop>,
-}
-
-#[cfg(not(windows))]
-pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
- extern {
- #[crate_map]
- static CRATE_MAP: CrateMap<'static>;
- }
-
- let ptr: (*CrateMap) = &'static CRATE_MAP;
- if ptr.is_null() {
- return None;
- } else {
- return Some(&'static CRATE_MAP);
- }
-}
-
-#[cfg(windows)]
-pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
- use cast::transmute;
- use c_str::ToCStr;
- use unstable::dynamic_lib::dl;
-
- let sym = unsafe {
- let module = dl::open_internal();
- let rust_crate_map_toplevel = if cfg!(target_arch = "x86") {
- "__rust_crate_map_toplevel"
- } else {
- "_rust_crate_map_toplevel"
- };
- let sym = rust_crate_map_toplevel.with_c_str(|buf| {
- dl::symbol(module, buf)
- });
- dl::close(module);
- sym
- };
- let ptr: (*CrateMap) = sym as *CrateMap;
- if ptr.is_null() {
- return None;
- } else {
- unsafe {
- return Some(transmute(sym));
- }
- }
-}
-
-fn version(crate_map: &CrateMap) -> i32 {
- match crate_map.version {
- 2 => return 2,
- _ => return 0
- }
-}
-
-fn do_iter_crate_map<'a>(
- crate_map: &'a CrateMap<'a>,
- f: |&ModEntry|,
- visited: &mut HashSet<*CrateMap<'a>>) {
- if visited.insert(crate_map as *CrateMap) {
- match version(crate_map) {
- 2 => {
- let (entries, children) = (crate_map.entries, crate_map.children);
- for entry in entries.iter() {
- f(entry);
- }
- for child in children.iter() {
- do_iter_crate_map(*child, |x| f(x), visited);
- }
- },
- _ => fail!("invalid crate map version")
- }
- }
-}
-
-/// Iterates recursively over `crate_map` and all child crate maps
-pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&ModEntry|) {
- // XXX: use random numbers as keys from the OS-level RNG when there is a nice
- // way to do this
- let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
- do_iter_crate_map(crate_map, f, &mut v);
-}
-
-#[cfg(test)]
-mod tests {
- use option::None;
- use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
-
- #[test]
- fn iter_crate_map_duplicates() {
- let mut level3: u32 = 3;
-
- let entries = [
- ModEntry { name: "c::m1", log_level: &mut level3},
- ];
-
- let child_crate = CrateMap {
- version: 2,
- entries: entries,
- children: [],
- event_loop_factory: None,
- };
-
- let root_crate = CrateMap {
- version: 2,
- entries: [],
- children: [&child_crate, &child_crate],
- event_loop_factory: None,
- };
-
- let mut cnt = 0;
- unsafe {
- iter_crate_map(&root_crate, |entry| {
- assert!(*entry.log_level == 3);
- cnt += 1;
- });
- assert!(cnt == 1);
- }
- }
-
- #[test]
- fn iter_crate_map_follow_children() {
- let mut level2: u32 = 2;
- let mut level3: u32 = 3;
- let child_crate2 = CrateMap {
- version: 2,
- entries: [
- ModEntry { name: "c::m1", log_level: &mut level2},
- ModEntry { name: "c::m2", log_level: &mut level3},
- ],
- children: [],
- event_loop_factory: None,
- };
-
- let child_crate1 = CrateMap {
- version: 2,
- entries: [
- ModEntry { name: "t::f1", log_level: &mut 1},
- ],
- children: [&child_crate2],
- event_loop_factory: None,
- };
-
- let root_crate = CrateMap {
- version: 2,
- entries: [
- ModEntry { name: "t::f2", log_level: &mut 0},
- ],
- children: [&child_crate1],
- event_loop_factory: None,
- };
-
- let mut cnt = 0;
- unsafe {
- iter_crate_map(&root_crate, |entry| {
- assert!(*entry.log_level == cnt);
- cnt += 1;
- });
- assert!(cnt == 4);
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Runtime environment settings
-
-use from_str::FromStr;
-use option::{Some, None};
-use os;
-
-// Note that these are all accessed without any synchronization.
-// They are expected to be initialized once then left alone.
-
-static mut MIN_STACK: uint = 2000000;
-static mut DEBUG_BORROW: bool = false;
-static mut POISON_ON_FREE: bool = false;
-
-pub fn init() {
- unsafe {
- match os::getenv("RUST_MIN_STACK") {
- Some(s) => match FromStr::from_str(s) {
- Some(i) => MIN_STACK = i,
- None => ()
- },
- None => ()
- }
- match os::getenv("RUST_DEBUG_BORROW") {
- Some(_) => DEBUG_BORROW = true,
- None => ()
- }
- match os::getenv("RUST_POISON_ON_FREE") {
- Some(_) => POISON_ON_FREE = true,
- None => ()
- }
- }
-}
-
-pub fn min_stack() -> uint {
- unsafe { MIN_STACK }
-}
-
-pub fn debug_borrow() -> bool {
- unsafe { DEBUG_BORROW }
-}
-
-pub fn poison_on_free() -> bool {
- unsafe { POISON_ON_FREE }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use libc::{c_void, c_char, size_t, uintptr_t, free, malloc, realloc};
-use unstable::intrinsics::TyDesc;
-use unstable::raw;
-use mem::size_of;
-
-extern {
- fn abort();
-}
-
-#[inline]
-pub fn get_box_size(body_size: uint, body_align: uint) -> uint {
- let header_size = size_of::<raw::Box<()>>();
- let total_size = align_to(header_size, body_align) + body_size;
- total_size
-}
-
-// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power
-// of two.
-#[inline]
-fn align_to(size: uint, align: uint) -> uint {
- assert!(align != 0);
- (size + align - 1) & !(align - 1)
-}
-
-/// A wrapper around libc::malloc, aborting on out-of-memory
-pub unsafe fn malloc_raw(size: uint) -> *c_void {
- let p = malloc(size as size_t);
- if p.is_null() {
- // we need a non-allocating way to print an error here
- abort();
- }
- p
-}
-
-/// A wrapper around libc::realloc, aborting on out-of-memory
-pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void {
- let p = realloc(ptr, size as size_t);
- if p.is_null() {
- // we need a non-allocating way to print an error here
- abort();
- }
- p
-}
-
-/// The allocator for unique pointers without contained managed pointers.
-#[cfg(not(test))]
-#[lang="exchange_malloc"]
-#[inline]
-pub unsafe fn exchange_malloc(size: uintptr_t) -> *c_char {
- malloc_raw(size as uint) as *c_char
-}
-
-// FIXME: #7496
-#[cfg(not(test))]
-#[lang="closure_exchange_malloc"]
-#[inline]
-pub unsafe fn closure_exchange_malloc_(td: *c_char, size: uintptr_t) -> *c_char {
- closure_exchange_malloc(td, size)
-}
-
-#[inline]
-pub unsafe fn closure_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
- let td = td as *TyDesc;
- let size = size as uint;
-
- assert!(td.is_not_null());
-
- let total_size = get_box_size(size, (*td).align);
- let p = malloc_raw(total_size as uint);
-
- let box = p as *mut raw::Box<()>;
- (*box).type_desc = td;
-
- box as *c_char
-}
-
-// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
-// inside a landing pad may corrupt the state of the exception handler.
-#[cfg(not(test))]
-#[lang="exchange_free"]
-#[inline]
-pub unsafe fn exchange_free_(ptr: *c_char) {
- exchange_free(ptr)
-}
-
-pub unsafe fn exchange_free(ptr: *c_char) {
- free(ptr as *c_void);
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
-
- #[bench]
- fn alloc_owned_small(bh: &mut BenchHarness) {
- bh.iter(|| {
- ~10;
- })
- }
-
- #[bench]
- fn alloc_owned_big(bh: &mut BenchHarness) {
- bh.iter(|| {
- ~[10, ..1000];
- })
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Task death: asynchronous killing, linked failure, exit code propagation.
-
-This file implements two orthogonal building-blocks for communicating failure
-between tasks. One is 'linked failure' or 'task killing', that is, a failing
-task causing other tasks to fail promptly (even those that are blocked on
-pipes or I/O). The other is 'exit code propagation', which affects the result
-observed by the parent of a task::try task that itself spawns child tasks
-(such as any #[test] function). In both cases the data structures live in
-KillHandle.
-
-
-I. Task killing.
-
-The model for killing involves two atomic flags, the "kill flag" and the
-"unkillable flag". Operations on the kill flag include:
-
-- In the taskgroup code (task/spawn.rs), tasks store a clone of their
- KillHandle in their shared taskgroup. Another task in the group that fails
- will use that handle to call kill().
-- When a task blocks, it turns its ~Task into a BlockedTask by storing a
- the transmuted ~Task pointer inside the KillHandle's kill flag. A task
- trying to block and a task trying to kill it can simultaneously access the
- kill flag, after which the task will get scheduled and fail (no matter who
- wins the race). Likewise, a task trying to wake a blocked task normally and
- a task trying to kill it can simultaneously access the flag; only one will
- get the task to reschedule it.
-
-Operations on the unkillable flag include:
-
-- When a task becomes unkillable, it swaps on the flag to forbid any killer
- from waking it up while it's blocked inside the unkillable section. If a
- kill was already pending, the task fails instead of becoming unkillable.
-- When a task is done being unkillable, it restores the flag to the normal
- running state. If a kill was received-but-blocked during the unkillable
- section, the task fails at this later point.
-- When a task tries to kill another task, before swapping on the kill flag, it
- first swaps on the unkillable flag, to see if it's "allowed" to wake up the
- task. If it isn't, the killed task will receive the signal when it becomes
- killable again. (Of course, a task trying to wake the task normally (e.g.
- sending on a channel) does not access the unkillable flag at all.)
-
-Why do we not need acquire/release barriers on any of the kill flag swaps?
-This is because barriers establish orderings between accesses on different
-memory locations, but each kill-related operation is only a swap on a single
-location, so atomicity is all that matters. The exception is kill(), which
-does a swap on both flags in sequence. kill() needs no barriers because it
-does not matter if its two accesses are seen reordered on another CPU: if a
-killer does perform both writes, it means it saw a KILL_RUNNING in the
-unkillable flag, which means an unkillable task will see KILL_KILLED and fail
-immediately (rendering the subsequent write to the kill flag unnecessary).
-
-
-II. Exit code propagation.
-
-The basic model for exit code propagation, which is used with the "watched"
-spawn mode (on by default for linked spawns, off for supervised and unlinked
-spawns), is that a parent will wait for all its watched children to exit
-before reporting whether it succeeded or failed. A watching parent will only
-report success if it succeeded and all its children also reported success;
-otherwise, it will report failure. This is most useful for writing test cases:
-
- ```
-#[test]
-fn test_something_in_another_task {
- do spawn {
- assert!(collatz_conjecture_is_false());
- }
-}
- ```
-
-Here, as the child task will certainly outlive the parent task, we might miss
-the failure of the child when deciding whether or not the test case passed.
-The watched spawn mode avoids this problem.
-
-In order to propagate exit codes from children to their parents, any
-'watching' parent must wait for all of its children to exit before it can
-report its final exit status. We achieve this by using an UnsafeArc, using the
-reference counting to track how many children are still alive, and using the
-unwrap() operation in the parent's exit path to wait for all children to exit.
-The UnsafeArc referred to here is actually the KillHandle itself.
-
-This also works transitively, as if a "middle" watched child task is itself
-watching a grandchild task, the "middle" task will do unwrap() on its own
-KillHandle (thereby waiting for the grandchild to exit) before dropping its
-reference to its watching parent (which will alert the parent).
-
-While UnsafeArc::unwrap() accomplishes the synchronization, there remains the
-matter of reporting the exit codes themselves. This is easiest when an exiting
-watched task has no watched children of its own:
-
-- If the task with no watched children exits successfully, it need do nothing.
-- If the task with no watched children has failed, it sets a flag in the
- parent's KillHandle ("any_child_failed") to false. It then stays false forever.
-
-However, if a "middle" watched task with watched children of its own exits
-before its child exits, we need to ensure that the grandparent task may still
-see a failure from the grandchild task. While we could achieve this by having
-each intermediate task block on its handle, this keeps around the other resources
-the task was using. To be more efficient, this is accomplished via "tombstones".
-
-A tombstone is a closure, proc() -> bool, which will perform any waiting necessary
-to collect the exit code of descendant tasks. In its environment is captured
-the KillHandle of whichever task created the tombstone, and perhaps also any
-tombstones that that task itself had, and finally also another tombstone,
-effectively creating a lazy-list of heap closures.
-
-When a child wishes to exit early and leave tombstones behind for its parent,
-it must use a LittleLock (pthread mutex) to synchronize with any possible
-sibling tasks which are trying to do the same thing with the same parent.
-However, on the other side, when the parent is ready to pull on the tombstones,
-it need not use this lock, because the unwrap() serves as a barrier that ensures
-no children will remain with references to the handle.
-
-The main logic for creating and assigning tombstones can be found in the
-function reparent_children_to() in the impl for KillHandle.
-
-
-IIA. Issues with exit code propagation.
-
-There are two known issues with the current scheme for exit code propagation.
-
-- As documented in issue #8136, the structure mandates the possibility for stack
- overflow when collecting tombstones that are very deeply nested. This cannot
- be avoided with the closure representation, as tombstones end up structured in
- a sort of tree. However, notably, the tombstones do not actually need to be
- collected in any particular order, and so a doubly-linked list may be used.
- However we do not do this yet because DList is in libextra.
-
-- A discussion with Graydon made me realize that if we decoupled the exit code
- propagation from the parents-waiting action, this could result in a simpler
- implementation as the exit codes themselves would not have to be propagated,
- and could instead be propagated implicitly through the taskgroup mechanism
- that we already have. The tombstoning scheme would still be required. I have
- not implemented this because currently we can't receive a linked failure kill
- signal during the task cleanup activity, as that is currently "unkillable",
- and occurs outside the task's unwinder's "try" block, so would require some
- restructuring.
-
-*/
-
-use cast;
-use cell::Cell;
-use option::{Option, Some, None};
-use prelude::*;
-use rt::task::Task;
-use rt::task::UnwindResult;
-use unstable::atomics::{AtomicUint, SeqCst};
-use unstable::sync::UnsafeArc;
-
-/// A handle to a blocked task. Usually this means having the ~Task pointer by
-/// ownership, but if the task is killable, a killer can steal it at any time.
-pub enum BlockedTask {
- Owned(~Task),
- Shared(UnsafeArc<AtomicUint>),
-}
-
-/// Per-task state related to task death, killing, failure, etc.
-pub struct Death {
- // Action to be done with the exit code. If set, also makes the task wait
- // until all its watched children exit before collecting the status.
- on_exit: Option<proc(UnwindResult)>,
- // nesting level counter for unstable::atomically calls (0 == can deschedule).
- priv wont_sleep: int,
-}
-
-impl BlockedTask {
- /// Returns Some if the task was successfully woken; None if already killed.
- pub fn wake(self) -> Option<~Task> {
- match self {
- Owned(task) => Some(task),
- Shared(arc) => unsafe {
- match (*arc.get()).swap(0, SeqCst) {
- 0 => None,
- n => cast::transmute(n),
- }
- }
- }
- }
-
- /// Create a blocked task, unless the task was already killed.
- pub fn block(task: ~Task) -> BlockedTask {
- Owned(task)
- }
-
- /// Converts one blocked task handle to a list of many handles to the same.
- pub fn make_selectable(self, num_handles: uint) -> ~[BlockedTask] {
- let handles = match self {
- Owned(task) => {
- let flag = unsafe {
- AtomicUint::new(cast::transmute(task))
- };
- UnsafeArc::newN(flag, num_handles)
- }
- Shared(arc) => arc.cloneN(num_handles),
- };
- // Even if the task was unkillable before, we use 'Killable' because
- // multiple pipes will have handles. It does not really mean killable.
- handles.move_iter().map(|x| Shared(x)).collect()
- }
-
- // This assertion has two flavours because the wake involves an atomic op.
- // In the faster version, destructors will fail dramatically instead.
- #[inline] #[cfg(not(test))]
- pub fn assert_already_awake(self) { }
- #[inline] #[cfg(test)]
- pub fn assert_already_awake(self) { assert!(self.wake().is_none()); }
-
- /// Convert to an unsafe uint value. Useful for storing in a pipe's state flag.
- #[inline]
- pub unsafe fn cast_to_uint(self) -> uint {
- match self {
- Owned(task) => {
- let blocked_task_ptr: uint = cast::transmute(task);
- rtassert!(blocked_task_ptr & 0x1 == 0);
- blocked_task_ptr
- }
- Shared(arc) => {
- let blocked_task_ptr: uint = cast::transmute(~arc);
- rtassert!(blocked_task_ptr & 0x1 == 0);
- blocked_task_ptr | 0x1
- }
- }
- }
-
- /// Convert from an unsafe uint value. Useful for retrieving a pipe's state flag.
- #[inline]
- pub unsafe fn cast_from_uint(blocked_task_ptr: uint) -> BlockedTask {
- if blocked_task_ptr & 0x1 == 0 {
- Owned(cast::transmute(blocked_task_ptr))
- } else {
- let ptr: ~UnsafeArc<AtomicUint> = cast::transmute(blocked_task_ptr & !1);
- Shared(*ptr)
- }
- }
-}
-
-impl Death {
- pub fn new() -> Death {
- Death {
- on_exit: None,
- wont_sleep: 0,
- }
- }
-
- /// Collect failure exit codes from children and propagate them to a parent.
- pub fn collect_failure(&mut self, result: UnwindResult) {
- let result = Cell::new(result);
- self.on_exit.take().map(|on_exit| on_exit(result.take()));
- }
-
- /// Enter a possibly-nested "atomic" section of code. Just for assertions.
- /// All calls must be paired with a subsequent call to allow_deschedule.
- #[inline]
- pub fn inhibit_deschedule(&mut self) {
- self.wont_sleep += 1;
- }
-
- /// Exit a possibly-nested "atomic" section of code. Just for assertions.
- /// All calls must be paired with a preceding call to inhibit_deschedule.
- #[inline]
- pub fn allow_deschedule(&mut self) {
- rtassert!(self.wont_sleep != 0);
- self.wont_sleep -= 1;
- }
-
- /// Ensure that the task is allowed to become descheduled.
- #[inline]
- pub fn assert_may_sleep(&self) {
- if self.wont_sleep != 0 {
- rtabort!("illegal atomic-sleep: attempt to reschedule while \
- using an Exclusive or LittleLock");
- }
- }
-}
-
-impl Drop for Death {
- fn drop(&mut self) {
- // Mustn't be in an atomic or unkillable section at task death.
- rtassert!(self.wont_sleep == 0);
- }
-}
-
-#[cfg(test)]
-mod test {
- use rt::test::*;
- use super::*;
-
- // Task blocking tests
-
- #[test]
- fn block_and_wake() {
- do with_test_task |task| {
- BlockedTask::block(task).wake().unwrap()
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use option::{Option, Some, None};
-use rt::sched::Scheduler;
-use rt::task::Task;
-use rt::local_ptr;
-use cell::Cell;
-
-pub trait Local {
- fn put(value: ~Self);
- fn take() -> ~Self;
- fn exists(unused_value: Option<Self>) -> bool;
- fn borrow<T>(f: |&mut Self| -> T) -> T;
- unsafe fn unsafe_take() -> ~Self;
- unsafe fn unsafe_borrow() -> *mut Self;
- unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
-}
-
-impl Local for Task {
- #[inline]
- fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
- #[inline]
- fn take() -> ~Task { unsafe { local_ptr::take() } }
- fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
- fn borrow<T>(f: |&mut Task| -> T) -> T {
- let mut res: Option<T> = None;
- let res_ptr: *mut Option<T> = &mut res;
- unsafe {
- local_ptr::borrow(|task| {
- let result = f(task);
- *res_ptr = Some(result);
- })
- }
- match res {
- Some(r) => { r }
- None => { rtabort!("function failed in local_borrow") }
- }
- }
- #[inline]
- unsafe fn unsafe_take() -> ~Task { local_ptr::unsafe_take() }
- #[inline]
- unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
- #[inline]
- unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
- local_ptr::try_unsafe_borrow()
- }
-}
-
-impl Local for Scheduler {
- fn put(value: ~Scheduler) {
- let value = Cell::new(value);
- Local::borrow(|task: &mut Task| {
- let task = task;
- task.sched = Some(value.take());
- });
- }
- #[inline]
- fn take() -> ~Scheduler {
- unsafe {
- // XXX: Unsafe for speed
- let task: *mut Task = Local::unsafe_borrow();
- (*task).sched.take_unwrap()
- }
- }
- fn exists(_: Option<Scheduler>) -> bool {
- Local::borrow(|task: &mut Task| {
- match task.sched {
- Some(ref _task) => true,
- None => false
- }
- })
- }
- fn borrow<T>(f: |&mut Scheduler| -> T) -> T {
- Local::borrow(|task: &mut Task| {
- match task.sched {
- Some(~ref mut task) => {
- f(task)
- }
- None => {
- rtabort!("no scheduler")
- }
- }
- })
- }
- unsafe fn unsafe_take() -> ~Scheduler { rtabort!("unimpl") }
- unsafe fn unsafe_borrow() -> *mut Scheduler {
- let task: *mut Task = Local::unsafe_borrow();
- match (*task).sched {
- Some(~ref mut sched) => {
- let s: *mut Scheduler = &mut *sched;
- return s;
- }
- None => {
- rtabort!("no scheduler")
- }
- }
- }
- unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> {
- let task_opt: Option<*mut Task> = Local::try_unsafe_borrow();
- match task_opt {
- Some(task) => {
- match (*task).sched {
- Some(~ref mut sched) => {
- let s: *mut Scheduler = &mut *sched;
- Some(s)
- }
- None => None
- }
- }
- None => None
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use option::None;
- use unstable::run_in_bare_thread;
- use rt::test::*;
- use super::*;
- use rt::task::Task;
- use rt::local_ptr;
-
- #[test]
- fn thread_local_task_smoke_test() {
- do run_in_bare_thread {
- local_ptr::init();
- let mut sched = ~new_test_uv_sched();
- let task = ~Task::new_root(&mut sched.stack_pool, None, proc(){});
- Local::put(task);
- let task: ~Task = Local::take();
- cleanup_task(task);
- }
- }
-
- #[test]
- fn thread_local_task_two_instances() {
- do run_in_bare_thread {
- local_ptr::init();
- let mut sched = ~new_test_uv_sched();
- let task = ~Task::new_root(&mut sched.stack_pool, None, proc(){});
- Local::put(task);
- let task: ~Task = Local::take();
- cleanup_task(task);
- let task = ~Task::new_root(&mut sched.stack_pool, None, proc(){});
- Local::put(task);
- let task: ~Task = Local::take();
- cleanup_task(task);
- }
-
- }
-
- #[test]
- fn borrow_smoke_test() {
- do run_in_bare_thread {
- local_ptr::init();
- let mut sched = ~new_test_uv_sched();
- let task = ~Task::new_root(&mut sched.stack_pool, None, proc(){});
- Local::put(task);
-
- unsafe {
- let _task: *mut Task = Local::unsafe_borrow();
- }
- let task: ~Task = Local::take();
- cleanup_task(task);
- }
- }
-
- #[test]
- fn borrow_with_return() {
- do run_in_bare_thread {
- local_ptr::init();
- let mut sched = ~new_test_uv_sched();
- let task = ~Task::new_root(&mut sched.stack_pool, None, proc(){});
- Local::put(task);
-
- let res = Local::borrow(|_task: &mut Task| {
- true
- });
- assert!(res)
- let task: ~Task = Local::take();
- cleanup_task(task);
- }
- }
-
-}
-
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The local, garbage collected heap
-
-use cast;
-use libc::{c_void, uintptr_t};
-use libc;
-use mem;
-use ops::Drop;
-use option::{Option, None, Some};
-use ptr;
-use rt::env;
-use rt::global_heap;
-use rt::local::Local;
-use rt::task::Task;
-use unstable::intrinsics::TyDesc;
-use unstable::raw;
-
-// This has no meaning with out rtdebug also turned on.
-static TRACK_ALLOCATIONS: int = 0;
-static MAGIC: u32 = 0xbadc0ffe;
-
-pub type Box = raw::Box<()>;
-
-pub struct MemoryRegion {
- priv allocations: ~[*AllocHeader],
- priv live_allocations: uint,
-}
-
-pub struct LocalHeap {
- priv memory_region: MemoryRegion,
-
- priv poison_on_free: bool,
- priv live_allocs: *mut raw::Box<()>,
-}
-
-impl LocalHeap {
- pub fn new() -> LocalHeap {
- let region = MemoryRegion {
- allocations: ~[],
- live_allocations: 0,
- };
- LocalHeap {
- memory_region: region,
- poison_on_free: env::poison_on_free(),
- live_allocs: ptr::mut_null(),
- }
- }
-
- pub fn alloc(&mut self, td: *TyDesc, size: uint) -> *mut Box {
- let total_size = global_heap::get_box_size(size, unsafe { (*td).align });
- let box = self.memory_region.malloc(total_size);
- {
- // Make sure that we can't use `mybox` outside of this scope
- let mybox: &mut Box = unsafe { cast::transmute(box) };
- // Clear out this box, and move it to the front of the live
- // allocations list
- mybox.type_desc = td;
- mybox.ref_count = 1;
- mybox.prev = ptr::mut_null();
- mybox.next = self.live_allocs;
- if !self.live_allocs.is_null() {
- unsafe { (*self.live_allocs).prev = box; }
- }
- self.live_allocs = box;
- }
- return box;
- }
-
- pub fn realloc(&mut self, ptr: *mut Box, size: uint) -> *mut Box {
- // Make sure that we can't use `mybox` outside of this scope
- let total_size = size + mem::size_of::<Box>();
- let new_box = self.memory_region.realloc(ptr, total_size);
- {
- // Fix links because we could have moved around
- let mybox: &mut Box = unsafe { cast::transmute(new_box) };
- if !mybox.prev.is_null() {
- unsafe { (*mybox.prev).next = new_box; }
- }
- if !mybox.next.is_null() {
- unsafe { (*mybox.next).prev = new_box; }
- }
- }
- if self.live_allocs == ptr {
- self.live_allocs = new_box;
- }
- return new_box;
- }
-
- pub fn free(&mut self, box: *mut Box) {
- {
- // Make sure that we can't use `mybox` outside of this scope
- let mybox: &mut Box = unsafe { cast::transmute(box) };
- assert!(!mybox.type_desc.is_null());
-
- // Unlink it from the linked list
- if !mybox.prev.is_null() {
- unsafe { (*mybox.prev).next = mybox.next; }
- }
- if !mybox.next.is_null() {
- unsafe { (*mybox.next).prev = mybox.prev; }
- }
- if self.live_allocs == box {
- self.live_allocs = mybox.next;
- }
-
- // Destroy the box memory-wise
- if self.poison_on_free {
- unsafe {
- let ptr: *mut u8 = cast::transmute(&mybox.data);
- ptr::set_memory(ptr, 0xab, (*mybox.type_desc).size);
- }
- }
- mybox.prev = ptr::mut_null();
- mybox.next = ptr::mut_null();
- mybox.type_desc = ptr::null();
- }
-
- self.memory_region.free(box);
- }
-}
-
-impl Drop for LocalHeap {
- fn drop(&mut self) {
- assert!(self.live_allocs.is_null());
- }
-}
-
-#[cfg(rtdebug)]
-struct AllocHeader {
- magic: u32,
- index: i32,
- size: u32,
-}
-#[cfg(not(rtdebug))]
-struct AllocHeader;
-
-impl AllocHeader {
- #[cfg(rtdebug)]
- fn init(&mut self, size: u32) {
- if TRACK_ALLOCATIONS > 0 {
- self.magic = MAGIC;
- self.index = -1;
- self.size = size;
- }
- }
- #[cfg(not(rtdebug))]
- fn init(&mut self, _size: u32) {}
-
- #[cfg(rtdebug)]
- fn assert_sane(&self) {
- if TRACK_ALLOCATIONS > 0 {
- rtassert!(self.magic == MAGIC);
- }
- }
- #[cfg(not(rtdebug))]
- fn assert_sane(&self) {}
-
- #[cfg(rtdebug)]
- fn update_size(&mut self, size: u32) {
- if TRACK_ALLOCATIONS > 0 {
- self.size = size;
- }
- }
- #[cfg(not(rtdebug))]
- fn update_size(&mut self, _size: u32) {}
-
- fn box(&mut self) -> *mut Box {
- let myaddr: uint = unsafe { cast::transmute(self) };
- (myaddr + AllocHeader::size()) as *mut Box
- }
-
- fn size() -> uint {
- // For some platforms, 16 byte alignment is required.
- let ptr_size = 16;
- let header_size = mem::size_of::<AllocHeader>();
- return (header_size + ptr_size - 1) / ptr_size * ptr_size;
- }
-
- fn from(box: *mut Box) -> *mut AllocHeader {
- (box as uint - AllocHeader::size()) as *mut AllocHeader
- }
-}
-
-impl MemoryRegion {
- fn malloc(&mut self, size: uint) -> *mut Box {
- let total_size = size + AllocHeader::size();
- let alloc: *AllocHeader = unsafe {
- global_heap::malloc_raw(total_size) as *AllocHeader
- };
-
- let alloc: &mut AllocHeader = unsafe { cast::transmute(alloc) };
- alloc.init(size as u32);
- self.claim(alloc);
- self.live_allocations += 1;
-
- return alloc.box();
- }
-
- fn realloc(&mut self, box: *mut Box, size: uint) -> *mut Box {
- rtassert!(!box.is_null());
- let orig_alloc = AllocHeader::from(box);
- unsafe { (*orig_alloc).assert_sane(); }
-
- let total_size = size + AllocHeader::size();
- let alloc: *AllocHeader = unsafe {
- global_heap::realloc_raw(orig_alloc as *mut libc::c_void,
- total_size) as *AllocHeader
- };
-
- let alloc: &mut AllocHeader = unsafe { cast::transmute(alloc) };
- alloc.assert_sane();
- alloc.update_size(size as u32);
- self.update(alloc, orig_alloc as *AllocHeader);
- return alloc.box();
- }
-
- fn free(&mut self, box: *mut Box) {
- rtassert!(!box.is_null());
- let alloc = AllocHeader::from(box);
- unsafe {
- (*alloc).assert_sane();
- self.release(cast::transmute(alloc));
- rtassert!(self.live_allocations > 0);
- self.live_allocations -= 1;
- global_heap::exchange_free(alloc as *libc::c_char)
- }
- }
-
- #[cfg(rtdebug)]
- fn claim(&mut self, alloc: &mut AllocHeader) {
- alloc.assert_sane();
- if TRACK_ALLOCATIONS > 1 {
- alloc.index = self.allocations.len() as i32;
- self.allocations.push(&*alloc as *AllocHeader);
- }
- }
- #[cfg(not(rtdebug))]
- fn claim(&mut self, _alloc: &mut AllocHeader) {}
-
- #[cfg(rtdebug)]
- fn release(&mut self, alloc: &AllocHeader) {
- alloc.assert_sane();
- if TRACK_ALLOCATIONS > 1 {
- rtassert!(self.allocations[alloc.index] == alloc as *AllocHeader);
- self.allocations[alloc.index] = ptr::null();
- }
- }
- #[cfg(not(rtdebug))]
- fn release(&mut self, _alloc: &AllocHeader) {}
-
- #[cfg(rtdebug)]
- fn update(&mut self, alloc: &mut AllocHeader, orig: *AllocHeader) {
- alloc.assert_sane();
- if TRACK_ALLOCATIONS > 1 {
- rtassert!(self.allocations[alloc.index] == orig);
- self.allocations[alloc.index] = &*alloc as *AllocHeader;
- }
- }
- #[cfg(not(rtdebug))]
- fn update(&mut self, _alloc: &mut AllocHeader, _orig: *AllocHeader) {}
-}
-
-impl Drop for MemoryRegion {
- fn drop(&mut self) {
- if self.live_allocations != 0 {
- rtabort!("leaked managed memory ({} objects)", self.live_allocations);
- }
- rtassert!(self.allocations.iter().all(|s| s.is_null()));
- }
-}
-
-pub unsafe fn local_malloc(td: *libc::c_char, size: libc::uintptr_t) -> *libc::c_char {
- // XXX: Unsafe borrow for speed. Lame.
- let task: Option<*mut Task> = Local::try_unsafe_borrow();
- match task {
- Some(task) => {
- (*task).heap.alloc(td as *TyDesc, size as uint) as *libc::c_char
- }
- None => rtabort!("local malloc outside of task")
- }
-}
-
-// A little compatibility function
-pub unsafe fn local_free(ptr: *libc::c_char) {
- // XXX: Unsafe borrow for speed. Lame.
- let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
- match task_ptr {
- Some(task) => {
- (*task).heap.free(ptr as *mut Box)
- }
- None => rtabort!("local free outside of task")
- }
-}
-
-pub fn live_allocs() -> *mut Box {
- Local::borrow(|task: &mut Task| task.heap.live_allocs)
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
-
- #[bench]
- fn alloc_managed_small(bh: &mut BenchHarness) {
- bh.iter(|| { @10; });
- }
-
- #[bench]
- fn alloc_managed_big(bh: &mut BenchHarness) {
- bh.iter(|| { @[10, ..1000]; });
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Access to a single thread-local pointer.
-//!
-//! The runtime will use this for storing ~Task.
-//!
-//! XXX: Add runtime checks for usage of inconsistent pointer types.
-//! and for overwriting an existing pointer.
-
-use cast;
-use cell::Cell;
-use unstable::finally::Finally;
-
-#[cfg(windows)] // mingw-w32 doesn't like thread_local things
-#[cfg(target_os = "android")] // see #10686
-pub use self::native::*;
-
-#[cfg(not(windows), not(target_os = "android"))]
-pub use self::compiled::*;
-
-/// Borrow the thread-local value from thread-local storage.
-/// While the value is borrowed it is not available in TLS.
-///
-/// # Safety note
-///
-/// Does not validate the pointer type.
-pub unsafe fn borrow<T>(f: |&mut T|) {
- let mut value = take();
-
- // XXX: Need a different abstraction from 'finally' here to avoid unsafety
- let unsafe_ptr = cast::transmute_mut_region(&mut *value);
- let value_cell = Cell::new(value);
-
- (|| f(unsafe_ptr)).finally(|| put(value_cell.take()));
-}
-
-/// Compiled implementation of accessing the runtime local pointer. This is
-/// implemented using LLVM's thread_local attribute which isn't necessarily
-/// working on all platforms. This implementation is faster, however, so we use
-/// it wherever possible.
-#[cfg(not(windows), not(target_os = "android"))]
-pub mod compiled {
- use libc::c_void;
- use cast;
- use option::{Option, Some, None};
-
- #[cfg(test)]
- pub use realstd::rt::shouldnt_be_public::RT_TLS_PTR;
-
- #[cfg(not(test))]
- #[thread_local]
- pub static mut RT_TLS_PTR: *mut c_void = 0 as *mut c_void;
-
- pub fn init() {}
-
- pub unsafe fn cleanup() {}
-
- /// Give a pointer to thread-local storage.
- ///
- /// # Safety note
- ///
- /// Does not validate the pointer type.
- #[inline]
- pub unsafe fn put<T>(sched: ~T) {
- RT_TLS_PTR = cast::transmute(sched)
- }
-
- /// Take ownership of a pointer from thread-local storage.
- ///
- /// # Safety note
- ///
- /// Does not validate the pointer type.
- #[inline]
- pub unsafe fn take<T>() -> ~T {
- let ptr: ~T = cast::transmute(RT_TLS_PTR);
- // can't use `as`, due to type not matching with `cfg(test)`
- RT_TLS_PTR = cast::transmute(0);
- ptr
- }
-
- /// Take ownership of a pointer from thread-local storage.
- ///
- /// # Safety note
- ///
- /// Does not validate the pointer type.
- /// Leaves the old pointer in TLS for speed.
- #[inline]
- pub unsafe fn unsafe_take<T>() -> ~T {
- cast::transmute(RT_TLS_PTR)
- }
-
- /// Check whether there is a thread-local pointer installed.
- pub fn exists() -> bool {
- unsafe {
- RT_TLS_PTR.is_not_null()
- }
- }
-
- pub unsafe fn unsafe_borrow<T>() -> *mut T {
- if RT_TLS_PTR.is_null() {
- rtabort!("thread-local pointer is null. bogus!");
- }
- RT_TLS_PTR as *mut T
- }
-
- pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
- if RT_TLS_PTR.is_null() {
- None
- } else {
- Some(RT_TLS_PTR as *mut T)
- }
- }
-}
-
-/// Native implementation of having the runtime thread-local pointer. This
-/// implementation uses the `thread_local_storage` module to provide a
-/// thread-local value.
-pub mod native {
- use cast;
- use libc::c_void;
- use option::{Option, Some, None};
- use ptr;
- use tls = rt::thread_local_storage;
- use unstable::mutex::{Mutex, MUTEX_INIT};
-
- static mut LOCK: Mutex = MUTEX_INIT;
- static mut INITIALIZED: bool = false;
- static mut RT_TLS_KEY: tls::Key = -1;
-
- /// Initialize the TLS key. Other ops will fail if this isn't executed
- /// first.
- pub fn init() {
- unsafe {
- LOCK.lock();
- if !INITIALIZED {
- tls::create(&mut RT_TLS_KEY);
- INITIALIZED = true;
- }
- LOCK.unlock();
- }
- }
-
- pub unsafe fn cleanup() {
- assert!(INITIALIZED);
- tls::destroy(RT_TLS_KEY);
- LOCK.destroy();
- INITIALIZED = false;
- }
-
- /// Give a pointer to thread-local storage.
- ///
- /// # Safety note
- ///
- /// Does not validate the pointer type.
- #[inline]
- pub unsafe fn put<T>(sched: ~T) {
- let key = tls_key();
- let void_ptr: *mut c_void = cast::transmute(sched);
- tls::set(key, void_ptr);
- }
-
- /// Take ownership of a pointer from thread-local storage.
- ///
- /// # Safety note
- ///
- /// Does not validate the pointer type.
- #[inline]
- pub unsafe fn take<T>() -> ~T {
- let key = tls_key();
- let void_ptr: *mut c_void = tls::get(key);
- if void_ptr.is_null() {
- rtabort!("thread-local pointer is null. bogus!");
- }
- let ptr: ~T = cast::transmute(void_ptr);
- tls::set(key, ptr::mut_null());
- return ptr;
- }
-
- /// Take ownership of a pointer from thread-local storage.
- ///
- /// # Safety note
- ///
- /// Does not validate the pointer type.
- /// Leaves the old pointer in TLS for speed.
- #[inline]
- pub unsafe fn unsafe_take<T>() -> ~T {
- let key = tls_key();
- let void_ptr: *mut c_void = tls::get(key);
- if void_ptr.is_null() {
- rtabort!("thread-local pointer is null. bogus!");
- }
- let ptr: ~T = cast::transmute(void_ptr);
- return ptr;
- }
-
- /// Check whether there is a thread-local pointer installed.
- pub fn exists() -> bool {
- unsafe {
- match maybe_tls_key() {
- Some(key) => tls::get(key).is_not_null(),
- None => false
- }
- }
- }
-
- /// Borrow a mutable reference to the thread-local value
- ///
- /// # Safety Note
- ///
- /// Because this leaves the value in thread-local storage it is possible
- /// For the Scheduler pointer to be aliased
- pub unsafe fn unsafe_borrow<T>() -> *mut T {
- let key = tls_key();
- let void_ptr = tls::get(key);
- if void_ptr.is_null() {
- rtabort!("thread-local pointer is null. bogus!");
- }
- void_ptr as *mut T
- }
-
- pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
- match maybe_tls_key() {
- Some(key) => {
- let void_ptr = tls::get(key);
- if void_ptr.is_null() {
- None
- } else {
- Some(void_ptr as *mut T)
- }
- }
- None => None
- }
- }
-
- #[inline]
- fn tls_key() -> tls::Key {
- match maybe_tls_key() {
- Some(key) => key,
- None => rtabort!("runtime tls key not initialized")
- }
- }
-
- #[inline]
- #[cfg(not(test))]
- pub fn maybe_tls_key() -> Option<tls::Key> {
- unsafe {
- // NB: This is a little racy because, while the key is
- // initalized under a mutex and it's assumed to be initalized
- // in the Scheduler ctor by any thread that needs to use it,
- // we are not accessing the key under a mutex. Threads that
- // are not using the new Scheduler but still *want to check*
- // whether they are running under a new Scheduler may see a 0
- // value here that is in the process of being initialized in
- // another thread. I think this is fine since the only action
- // they could take if it was initialized would be to check the
- // thread-local value and see that it's not set.
- if RT_TLS_KEY != -1 {
- return Some(RT_TLS_KEY);
- } else {
- return None;
- }
- }
- }
-
- #[inline] #[cfg(test)]
- pub fn maybe_tls_key() -> Option<tls::Key> {
- use realstd;
- unsafe {
- cast::transmute(realstd::rt::shouldnt_be_public::maybe_tls_key())
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use fmt;
-use from_str::from_str;
-use libc::exit;
-use option::{Some, None, Option};
-use io;
-use io::stdio::StdWriter;
-use io::buffered::LineBufferedWriter;
-use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
-use str::StrSlice;
-use u32;
-use vec::ImmutableVector;
-#[cfg(test)] use cast::transmute;
-
-struct LogDirective {
- name: Option<~str>,
- level: u32
-}
-
-static MAX_LOG_LEVEL: u32 = 255;
-static DEFAULT_LOG_LEVEL: u32 = 1;
-static log_level_names : &'static[&'static str] = &'static["error", "warn", "info", "debug"];
-
-/// Parse an individual log level that is either a number or a symbolic log level
-fn parse_log_level(level: &str) -> Option<u32> {
- let num = from_str::<u32>(level);
- let mut log_level;
- match num {
- Some(num) => {
- if num < MAX_LOG_LEVEL {
- log_level = Some(num);
- } else {
- log_level = Some(MAX_LOG_LEVEL);
- }
- }
- _ => {
- let position = log_level_names.iter().position(|&name| name == level);
- match position {
- Some(position) => {
- log_level = Some(u32::min(MAX_LOG_LEVEL, (position + 1) as u32))
- },
- _ => {
- log_level = None;
- }
- }
- }
- }
- log_level
-}
-
-/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1")
-/// and return a vector with log directives.
-/// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in std::).
-/// Also supports string log levels of error, warn, info, and debug
-fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
- let mut dirs = ~[];
- for s in spec.split(',') {
- let parts: ~[&str] = s.split('=').collect();
- let mut log_level;
- let mut name = Some(parts[0].to_owned());
- match parts.len() {
- 1 => {
- //if the single argument is a log-level string or number,
- //treat that as a global fallback
- let possible_log_level = parse_log_level(parts[0]);
- match possible_log_level {
- Some(num) => {
- name = None;
- log_level = num;
- },
- _ => {
- log_level = MAX_LOG_LEVEL
- }
- }
- }
- 2 => {
- let possible_log_level = parse_log_level(parts[1]);
- match possible_log_level {
- Some(num) => {
- log_level = num;
- },
- _ => {
- rterrln!("warning: invalid logging spec '{}', \
- ignoring it", parts[1]);
- continue
- }
- }
- },
- _ => {
- rterrln!("warning: invalid logging spec '{}', \
- ignoring it", s);
- continue
- }
- }
- let dir = LogDirective {name: name, level: log_level};
- dirs.push(dir);
- }
- return dirs;
-}
-
-/// Set the log level of an entry in the crate map depending on the vector
-/// of log directives
-fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
- let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
- let mut longest_match = -1i;
- for dir in dirs.iter() {
- match dir.name {
- None => {
- if longest_match == -1 {
- longest_match = 0;
- new_lvl = dir.level;
- }
- }
- Some(ref dir_name) => {
- let name = entry.name;
- let len = dir_name.len() as int;
- if name.starts_with(*dir_name) &&
- len >= longest_match {
- longest_match = len;
- new_lvl = dir.level;
- }
- }
- };
- }
- unsafe { *entry.log_level = new_lvl; }
- if longest_match >= 0 { return 1; } else { return 0; }
-}
-
-/// Set log level for every entry in crate_map according to the sepecification
-/// in settings
-fn update_log_settings(crate_map: &CrateMap, settings: ~str) {
- let mut dirs = ~[];
- if settings.len() > 0 {
- if settings == ~"::help" || settings == ~"?" {
- rterrln!("\nCrate log map:\n");
- iter_crate_map(crate_map, |entry| rterrln!(" {}", entry.name));
- unsafe { exit(1); }
- }
- dirs = parse_logging_spec(settings);
- }
-
- let mut n_matches: u32 = 0;
- iter_crate_map(crate_map, |entry| {
- let m = update_entry(dirs, entry);
- n_matches += m;
- });
-
- if n_matches < (dirs.len() as u32) {
- rterrln!("warning: got {} RUST_LOG specs but only matched\n\
- {} of them. You may have mistyped a RUST_LOG spec. \n\
- Use RUST_LOG=::help to see the list of crates and modules.\n",
- dirs.len(), n_matches);
- }
-}
-
-pub trait Logger {
- fn log(&mut self, args: &fmt::Arguments);
-}
-
-/// This logger emits output to the stderr of the process, and contains a lazily
-/// initialized event-loop driven handle to the stream.
-pub struct StdErrLogger {
- priv handle: LineBufferedWriter<StdWriter>,
-}
-
-impl StdErrLogger {
- pub fn new() -> StdErrLogger {
- StdErrLogger { handle: LineBufferedWriter::new(io::stderr()) }
- }
-}
-
-impl Logger for StdErrLogger {
- fn log(&mut self, args: &fmt::Arguments) {
- fmt::writeln(&mut self.handle as &mut io::Writer, args);
- }
-}
-
-/// Configure logging by traversing the crate map and setting the
-/// per-module global logging flags based on the logging spec
-pub fn init() {
- use os;
-
- let log_spec = os::getenv("RUST_LOG");
- match get_crate_map() {
- Some(crate_map) => {
- match log_spec {
- Some(spec) => {
- update_log_settings(crate_map, spec);
- }
- None => {
- update_log_settings(crate_map, ~"");
- }
- }
- },
- _ => {
- match log_spec {
- Some(_) => {
- rterrln!("warning: RUST_LOG set, but no crate map found.");
- },
- None => {}
- }
- }
- }
-}
-
-// Tests for parse_logging_spec()
-#[test]
-fn parse_logging_spec_valid() {
- let dirs = parse_logging_spec(~"crate1::mod1=1,crate1::mod2,crate2=4");
- assert_eq!(dirs.len(), 3);
- assert!(dirs[0].name == Some(~"crate1::mod1"));
- assert_eq!(dirs[0].level, 1);
-
- assert!(dirs[1].name == Some(~"crate1::mod2"));
- assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
-
- assert!(dirs[2].name == Some(~"crate2"));
- assert_eq!(dirs[2].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_invalid_crate() {
- // test parse_logging_spec with multiple = in specification
- let dirs = parse_logging_spec(~"crate1::mod1=1=2,crate2=4");
- assert_eq!(dirs.len(), 1);
- assert!(dirs[0].name == Some(~"crate2"));
- assert_eq!(dirs[0].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_invalid_log_level() {
- // test parse_logging_spec with 'noNumber' as log level
- let dirs = parse_logging_spec(~"crate1::mod1=noNumber,crate2=4");
- assert_eq!(dirs.len(), 1);
- assert!(dirs[0].name == Some(~"crate2"));
- assert_eq!(dirs[0].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_string_log_level() {
- // test parse_logging_spec with 'warn' as log level
- let dirs = parse_logging_spec(~"crate1::mod1=wrong,crate2=warn");
- assert_eq!(dirs.len(), 1);
- assert!(dirs[0].name == Some(~"crate2"));
- assert_eq!(dirs[0].level, 2);
-}
-
-#[test]
-fn parse_logging_spec_global() {
- // test parse_logging_spec with no crate
- let dirs = parse_logging_spec(~"warn,crate2=4");
- assert_eq!(dirs.len(), 2);
- assert!(dirs[0].name == None);
- assert_eq!(dirs[0].level, 2);
- assert!(dirs[1].name == Some(~"crate2"));
- assert_eq!(dirs[1].level, 4);
-}
-
-// Tests for update_entry
-#[test]
-fn update_entry_match_full_path() {
- let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
- LogDirective {name: Some(~"crate2"), level: 3}];
- let level = &mut 0;
- unsafe {
- let entry= &ModEntry {name:"crate1::mod1", log_level: level};
- let m = update_entry(dirs, transmute(entry));
- assert!(*entry.log_level == 2);
- assert!(m == 1);
- }
-}
-
-#[test]
-fn update_entry_no_match() {
- let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
- LogDirective {name: Some(~"crate2"), level: 3}];
- let level = &mut 0;
- unsafe {
- let entry= &ModEntry {name: "crate3::mod1", log_level: level};
- let m = update_entry(dirs, transmute(entry));
- assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
- assert!(m == 0);
- }
-}
-
-#[test]
-fn update_entry_match_beginning() {
- let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
- LogDirective {name: Some(~"crate2"), level: 3}];
- let level = &mut 0;
- unsafe {
- let entry= &ModEntry {name: "crate2::mod1", log_level: level};
- let m = update_entry(dirs, transmute(entry));
- assert!(*entry.log_level == 3);
- assert!(m == 1);
- }
-}
-
-#[test]
-fn update_entry_match_beginning_longest_match() {
- let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
- LogDirective {name: Some(~"crate2"), level: 3},
- LogDirective {name: Some(~"crate2::mod"), level: 4}];
- let level = &mut 0;
- unsafe {
- let entry = &ModEntry {name: "crate2::mod1", log_level: level};
- let m = update_entry(dirs, transmute(entry));
- assert!(*entry.log_level == 4);
- assert!(m == 1);
- }
-}
-
-#[test]
-fn update_entry_match_default() {
- let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
- LogDirective {name: None, level: 3}
- ];
- let level = &mut 0;
- unsafe {
- let entry= &ModEntry {name: "crate1::mod1", log_level: level};
- let m = update_entry(dirs, transmute(entry));
- assert!(*entry.log_level == 2);
- assert!(m == 1);
- let entry= &ModEntry {name: "crate2::mod2", log_level: level};
- let m = update_entry(dirs, transmute(entry));
- assert!(*entry.log_level == 3);
- assert!(m == 1);
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Macros used by the runtime.
-//!
-//! These macros call functions which are only accessible in the `rt` module, so
-//! they aren't defined anywhere outside of the `rt` module.
-
-#[macro_escape];
-
-macro_rules! rterrln (
- ($($arg:tt)*) => ( {
- format_args!(::rt::util::dumb_println, $($arg)*)
- } )
-)
-
-// Some basic logging. Enabled by passing `--cfg rtdebug` to the libstd build.
-macro_rules! rtdebug (
- ($($arg:tt)*) => ( {
- if cfg!(rtdebug) {
- rterrln!($($arg)*)
- }
- })
-)
-
-macro_rules! rtassert (
- ( $arg:expr ) => ( {
- if ::rt::util::ENFORCE_SANITY {
- if !$arg {
- rtabort!(" assertion failed: {}", stringify!($arg));
- }
- }
- } )
-)
-
-
-macro_rules! rtabort (
- ($($arg:tt)*) => ( {
- ::rt::util::abort(format!($($arg)*));
- } )
-)
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A concurrent queue that supports multiple producers and a
-//! single consumer.
-
-use kinds::Send;
-use vec::OwnedVector;
-use option::Option;
-use clone::Clone;
-use rt::mpsc_queue::Queue;
-
-pub struct MessageQueue<T> {
- priv queue: Queue<T>
-}
-
-impl<T: Send> MessageQueue<T> {
- pub fn new() -> MessageQueue<T> {
- MessageQueue {
- queue: Queue::new()
- }
- }
-
- #[inline]
- pub fn push(&mut self, value: T) {
- self.queue.push(value)
- }
-
- #[inline]
- pub fn pop(&mut self) -> Option<T> {
- self.queue.pop()
- }
-
- /// A pop that may sometimes miss enqueued elements, but is much faster
- /// to give up without doing any synchronization
- #[inline]
- pub fn casual_pop(&mut self) -> Option<T> {
- self.queue.pop()
- }
-}
-
-impl<T: Send> Clone for MessageQueue<T> {
- fn clone(&self) -> MessageQueue<T> {
- MessageQueue {
- queue: self.queue.clone()
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! The Rust Runtime, including the task scheduler and I/O
-
-The `rt` module provides the private runtime infrastructure necessary
-to support core language features like the exchange and local heap,
-the garbage collector, logging, local data and unwinding. It also
-implements the default task scheduler and task model. Initialization
-routines are provided for setting up runtime resources in common
-configurations, including that used by `rustc` when generating
-executables.
-
-It is intended that the features provided by `rt` can be factored in a
-way such that the core library can be built with different 'profiles'
-for different use cases, e.g. excluding the task scheduler. A number
-of runtime features though are critical to the functioning of the
-language and an implementation must be provided regardless of the
-execution environment.
-
-Of foremost importance is the global exchange heap, in the module
-`global_heap`. Very little practical Rust code can be written without
-access to the global heap. Unlike most of `rt` the global heap is
-truly a global resource and generally operates independently of the
-rest of the runtime.
-
-All other runtime features are task-local, including the local heap,
-the garbage collector, local storage, logging and the stack unwinder.
-
-The relationship between `rt` and the rest of the core library is
-not entirely clear yet and some modules will be moving into or
-out of `rt` as development proceeds.
-
-Several modules in `core` are clients of `rt`:
-
-* `std::task` - The user-facing interface to the Rust task model.
-* `std::task::local_data` - The interface to local data.
-* `std::gc` - The garbage collector.
-* `std::unstable::lang` - Miscellaneous lang items, some of which rely on `std::rt`.
-* `std::condition` - Uses local data.
-* `std::cleanup` - Local heap destruction.
-* `std::io` - In the future `std::io` will use an `rt` implementation.
-* `std::logging`
-* `std::pipes`
-* `std::comm`
-* `std::stackwalk`
-
-*/
-
-// XXX: this should not be here.
-#[allow(missing_doc)];
-
-use cell::Cell;
-use clone::Clone;
-use container::Container;
-use iter::Iterator;
-use option::{Option, None, Some};
-use ptr::RawPtr;
-use rt::local::Local;
-use rt::sched::{Scheduler, Shutdown};
-use rt::sleeper_list::SleeperList;
-use rt::task::UnwindResult;
-use rt::task::{Task, SchedTask, GreenTask, Sched};
-use send_str::SendStrStatic;
-use unstable::atomics::{AtomicInt, AtomicBool, SeqCst};
-use unstable::sync::UnsafeArc;
-use vec::{OwnedVector, MutableVector, ImmutableVector};
-use vec;
-
-use self::thread::Thread;
-use self::work_queue::WorkQueue;
-
-// the os module needs to reach into this helper, so allow general access
-// through this reexport.
-pub use self::util::set_exit_status;
-
-// this is somewhat useful when a program wants to spawn a "reasonable" number
-// of workers based on the constraints of the system that it's running on.
-// Perhaps this shouldn't be a `pub use` though and there should be another
-// method...
-pub use self::util::default_sched_threads;
-
-// Re-export of the functionality in the kill module
-pub use self::kill::BlockedTask;
-
-// XXX: these probably shouldn't be public...
-#[doc(hidden)]
-pub mod shouldnt_be_public {
- pub use super::select::SelectInner;
- pub use super::select::{SelectInner, SelectPortInner};
- pub use super::local_ptr::native::maybe_tls_key;
- #[cfg(not(windows), not(target_os = "android"))]
- pub use super::local_ptr::compiled::RT_TLS_PTR;
-}
-
-// Internal macros used by the runtime.
-mod macros;
-
-/// Basic implementation of an EventLoop, provides no I/O interfaces
-mod basic;
-
-/// The global (exchange) heap.
-pub mod global_heap;
-
-/// Implementations of language-critical runtime features like @.
-pub mod task;
-
-/// Facilities related to task failure, killing, and death.
-mod kill;
-
-/// The coroutine task scheduler, built on the `io` event loop.
-pub mod sched;
-
-#[cfg(stage0)]
-pub mod io {
- pub use io::stdio;
-}
-
-/// The EventLoop and internal synchronous I/O interface.
-pub mod rtio;
-
-/// The Local trait for types that are accessible via thread-local
-/// or task-local storage.
-pub mod local;
-
-/// A parallel work-stealing deque.
-pub mod work_queue;
-
-/// A parallel queue.
-pub mod message_queue;
-
-/// A mostly lock-free multi-producer, single consumer queue.
-mod mpsc_queue;
-
-/// A lock-free multi-producer, multi-consumer bounded queue.
-mod mpmc_bounded_queue;
-
-/// A parallel data structure for tracking sleeping schedulers.
-pub mod sleeper_list;
-
-/// Stack segments and caching.
-pub mod stack;
-
-/// CPU context swapping.
-mod context;
-
-/// Bindings to system threading libraries.
-pub mod thread;
-
-/// The runtime configuration, read from environment variables.
-pub mod env;
-
-/// The local, managed heap
-pub mod local_heap;
-
-/// The Logger trait and implementations
-pub mod logging;
-
-/// Crate map
-pub mod crate_map;
-
-/// Tools for testing the runtime
-pub mod test;
-
-/// Reference counting
-pub mod rc;
-
-/// A simple single-threaded channel type for passing buffered data between
-/// scheduler and task context
-pub mod tube;
-
-/// Simple reimplementation of std::comm
-pub mod comm;
-
-mod select;
-
-/// The runtime needs to be able to put a pointer into thread-local storage.
-mod local_ptr;
-
-/// Bindings to pthread/windows thread-local storage.
-mod thread_local_storage;
-
-/// Just stuff
-mod util;
-
-// Global command line argument storage
-pub mod args;
-
-// Support for dynamic borrowck
-pub mod borrowck;
-
-/// Set up a default runtime configuration, given compiler-supplied arguments.
-///
-/// This is invoked by the `start` _language item_ (unstable::lang) to
-/// run a Rust executable.
-///
-/// # Arguments
-///
-/// * `argc` & `argv` - The argument vector. On Unix this information is used
-/// by os::args.
-///
-/// # Return value
-///
-/// The return value is used as the process return code. 0 on success, 101 on error.
-pub fn start(argc: int, argv: **u8, main: proc()) -> int {
-
- init(argc, argv);
- let exit_code = run(main);
- // unsafe is ok b/c we're sure that the runtime is gone
- unsafe { cleanup(); }
-
- return exit_code;
-}
-
-/// Like `start` but creates an additional scheduler on the current thread,
-/// which in most cases will be the 'main' thread, and pins the main task to it.
-///
-/// This is appropriate for running code that must execute on the main thread,
-/// such as the platform event loop and GUI.
-pub fn start_on_main_thread(argc: int, argv: **u8, main: proc()) -> int {
- init(argc, argv);
- let exit_code = run_on_main_thread(main);
- // unsafe is ok b/c we're sure that the runtime is gone
- unsafe { cleanup(); }
-
- return exit_code;
-}
-
-/// One-time runtime initialization.
-///
-/// Initializes global state, including frobbing
-/// the crate's logging flags, registering GC
-/// metadata, and storing the process arguments.
-pub fn init(argc: int, argv: **u8) {
- // XXX: Derefing these pointers is not safe.
- // Need to propagate the unsafety to `start`.
- unsafe {
- args::init(argc, argv);
- env::init();
- logging::init();
- }
-}
-
-/// One-time runtime cleanup.
-///
-/// This function is unsafe because it performs no checks to ensure that the
-/// runtime has completely ceased running. It is the responsibility of the
-/// caller to ensure that the runtime is entirely shut down and nothing will be
-/// poking around at the internal components.
-///
-/// Invoking cleanup while portions of the runtime are still in use may cause
-/// undefined behavior.
-pub unsafe fn cleanup() {
- args::cleanup();
- local_ptr::cleanup();
-}
-
-/// Execute the main function in a scheduler.
-///
-/// Configures the runtime according to the environment, by default
-/// using a task scheduler with the same number of threads as cores.
-/// Returns a process exit code.
-pub fn run(main: proc()) -> int {
- run_(main, false)
-}
-
-pub fn run_on_main_thread(main: proc()) -> int {
- run_(main, true)
-}
-
-fn run_(main: proc(), use_main_sched: bool) -> int {
- static DEFAULT_ERROR_CODE: int = 101;
-
- let nscheds = util::default_sched_threads();
-
- let main = Cell::new(main);
-
- // The shared list of sleeping schedulers.
- let sleepers = SleeperList::new();
-
- // Create a work queue for each scheduler, ntimes. Create an extra
- // for the main thread if that flag is set. We won't steal from it.
- let work_queues: ~[WorkQueue<~Task>] = vec::from_fn(nscheds, |_| WorkQueue::new());
-
- // The schedulers.
- let mut scheds = ~[];
- // Handles to the schedulers. When the main task ends these will be
- // sent the Shutdown message to terminate the schedulers.
- let mut handles = ~[];
-
- for work_queue in work_queues.iter() {
- rtdebug!("inserting a regular scheduler");
-
- // Every scheduler is driven by an I/O event loop.
- let loop_ = new_event_loop();
- let mut sched = ~Scheduler::new(loop_,
- work_queue.clone(),
- work_queues.clone(),
- sleepers.clone());
- let handle = sched.make_handle();
-
- scheds.push(sched);
- handles.push(handle);
- }
-
- // If we need a main-thread task then create a main thread scheduler
- // that will reject any task that isn't pinned to it
- let main_sched = if use_main_sched {
-
- // Create a friend handle.
- let mut friend_sched = scheds.pop();
- let friend_handle = friend_sched.make_handle();
- scheds.push(friend_sched);
-
- // This scheduler needs a queue that isn't part of the stealee
- // set.
- let work_queue = WorkQueue::new();
-
- let main_loop = new_event_loop();
- let mut main_sched = ~Scheduler::new_special(main_loop,
- work_queue,
- work_queues.clone(),
- sleepers.clone(),
- false,
- Some(friend_handle));
- let mut main_handle = main_sched.make_handle();
- // Allow the scheduler to exit when the main task exits.
- // Note: sending the shutdown message also prevents the scheduler
- // from pushing itself to the sleeper list, which is used for
- // waking up schedulers for work stealing; since this is a
- // non-work-stealing scheduler it should not be adding itself
- // to the list.
- main_handle.send(Shutdown);
- Some(main_sched)
- } else {
- None
- };
-
- // Create a shared cell for transmitting the process exit
- // code from the main task to this function.
- let exit_code = UnsafeArc::new(AtomicInt::new(0));
- let exit_code_clone = exit_code.clone();
-
- // Used to sanity check that the runtime only exits once
- let exited_already = UnsafeArc::new(AtomicBool::new(false));
-
- // When the main task exits, after all the tasks in the main
- // task tree, shut down the schedulers and set the exit code.
- let handles = handles;
- let on_exit: proc(UnwindResult) = proc(exit_success) {
- unsafe {
- assert!(!(*exited_already.get()).swap(true, SeqCst),
- "the runtime already exited");
- }
-
- let mut handles = handles;
- for handle in handles.mut_iter() {
- handle.send(Shutdown);
- }
-
- unsafe {
- let exit_code = if exit_success.is_success() {
- use rt::util;
-
- // If we're exiting successfully, then return the global
- // exit status, which can be set programmatically.
- util::get_exit_status()
- } else {
- DEFAULT_ERROR_CODE
- };
- (*exit_code_clone.get()).store(exit_code, SeqCst);
- }
- };
-
- let mut threads = ~[];
-
- let on_exit = Cell::new(on_exit);
-
- if !use_main_sched {
-
- // In the case where we do not use a main_thread scheduler we
- // run the main task in one of our threads.
-
- let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, main.take());
- main_task.name = Some(SendStrStatic("<main>"));
- main_task.death.on_exit = Some(on_exit.take());
- let main_task_cell = Cell::new(main_task);
-
- let sched = scheds.pop();
- let sched_cell = Cell::new(sched);
- let thread = do Thread::start {
- let sched = sched_cell.take();
- sched.bootstrap(main_task_cell.take());
- };
- threads.push(thread);
- }
-
- // Run each remaining scheduler in a thread.
- for sched in scheds.move_rev_iter() {
- rtdebug!("creating regular schedulers");
- let sched_cell = Cell::new(sched);
- let thread = do Thread::start {
- let mut sched = sched_cell.take();
- let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
- rtdebug!("boostraping a non-primary scheduler");
- };
- sched.bootstrap(bootstrap_task);
- };
- threads.push(thread);
- }
-
- // If we do have a main thread scheduler, run it now.
-
- if use_main_sched {
-
- rtdebug!("about to create the main scheduler task");
-
- let mut main_sched = main_sched.unwrap();
-
- let home = Sched(main_sched.make_handle());
- let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool, None,
- home, main.take());
- main_task.name = Some(SendStrStatic("<main>"));
- main_task.death.on_exit = Some(on_exit.take());
- rtdebug!("bootstrapping main_task");
-
- main_sched.bootstrap(main_task);
- }
-
- rtdebug!("waiting for threads");
-
- // Wait for schedulers
- for thread in threads.move_iter() {
- thread.join();
- }
-
- // Return the exit code
- unsafe {
- (*exit_code.get()).load(SeqCst)
- }
-}
-
-pub fn in_sched_context() -> bool {
- unsafe {
- let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
- match task_ptr {
- Some(task) => {
- match (*task).task_type {
- SchedTask => true,
- _ => false
- }
- }
- None => false
- }
- }
-}
-
-pub fn in_green_task_context() -> bool {
- unsafe {
- let task: Option<*mut Task> = Local::try_unsafe_borrow();
- match task {
- Some(task) => {
- match (*task).task_type {
- GreenTask(_) => true,
- _ => false
- }
- }
- None => false
- }
- }
-}
-
-pub fn new_event_loop() -> ~rtio::EventLoop {
- match crate_map::get_crate_map() {
- None => {}
- Some(map) => {
- match map.event_loop_factory {
- None => {}
- Some(factory) => return factory()
- }
- }
- }
-
- // If the crate map didn't specify a factory to create an event loop, then
- // instead just use a basic event loop missing all I/O services to at least
- // get the scheduler running.
- return basic::event_loop();
-}
+++ /dev/null
-/* Multi-producer/multi-consumer bounded queue
- * Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-// http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
-
-use unstable::sync::UnsafeArc;
-use unstable::atomics::{AtomicUint,Relaxed,Release,Acquire};
-use option::*;
-use vec;
-use clone::Clone;
-use kinds::Send;
-use num::{Exponential,Algebraic,Round};
-
-struct Node<T> {
- sequence: AtomicUint,
- value: Option<T>,
-}
-
-struct State<T> {
- pad0: [u8, ..64],
- buffer: ~[Node<T>],
- mask: uint,
- pad1: [u8, ..64],
- enqueue_pos: AtomicUint,
- pad2: [u8, ..64],
- dequeue_pos: AtomicUint,
- pad3: [u8, ..64],
-}
-
-struct Queue<T> {
- priv state: UnsafeArc<State<T>>,
-}
-
-impl<T: Send> State<T> {
- fn with_capacity(capacity: uint) -> State<T> {
- let capacity = if capacity < 2 || (capacity & (capacity - 1)) != 0 {
- if capacity < 2 {
- 2u
- } else {
- // use next power of 2 as capacity
- 2f64.pow(&((capacity as f64).log2().ceil())) as uint
- }
- } else {
- capacity
- };
- let buffer = vec::from_fn(capacity, |i:uint| {
- Node{sequence:AtomicUint::new(i),value:None}
- });
- State{
- pad0: [0, ..64],
- buffer: buffer,
- mask: capacity-1,
- pad1: [0, ..64],
- enqueue_pos: AtomicUint::new(0),
- pad2: [0, ..64],
- dequeue_pos: AtomicUint::new(0),
- pad3: [0, ..64],
- }
- }
-
- fn push(&mut self, value: T) -> bool {
- let mask = self.mask;
- let mut pos = self.enqueue_pos.load(Relaxed);
- loop {
- let node = &mut self.buffer[pos & mask];
- let seq = node.sequence.load(Acquire);
- let diff: int = seq as int - pos as int;
-
- if diff == 0 {
- let enqueue_pos = self.enqueue_pos.compare_and_swap(pos, pos+1, Relaxed);
- if enqueue_pos == pos {
- node.value = Some(value);
- node.sequence.store(pos+1, Release);
- break
- } else {
- pos = enqueue_pos;
- }
- } else if (diff < 0) {
- return false
- } else {
- pos = self.enqueue_pos.load(Relaxed);
- }
- }
- true
- }
-
- fn pop(&mut self) -> Option<T> {
- let mask = self.mask;
- let mut pos = self.dequeue_pos.load(Relaxed);
- loop {
- let node = &mut self.buffer[pos & mask];
- let seq = node.sequence.load(Acquire);
- let diff: int = seq as int - (pos + 1) as int;
- if diff == 0 {
- let dequeue_pos = self.dequeue_pos.compare_and_swap(pos, pos+1, Relaxed);
- if dequeue_pos == pos {
- let value = node.value.take();
- node.sequence.store(pos + mask + 1, Release);
- return value
- } else {
- pos = dequeue_pos;
- }
- } else if diff < 0 {
- return None
- } else {
- pos = self.dequeue_pos.load(Relaxed);
- }
- }
- }
-}
-
-impl<T: Send> Queue<T> {
- pub fn with_capacity(capacity: uint) -> Queue<T> {
- Queue{
- state: UnsafeArc::new(State::with_capacity(capacity))
- }
- }
-
- pub fn push(&mut self, value: T) -> bool {
- unsafe { (*self.state.get()).push(value) }
- }
-
- pub fn pop(&mut self) -> Option<T> {
- unsafe { (*self.state.get()).pop() }
- }
-}
-
-impl<T: Send> Clone for Queue<T> {
- fn clone(&self) -> Queue<T> {
- Queue {
- state: self.state.clone()
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use option::*;
- use task;
- use comm;
- use super::Queue;
-
- #[test]
- fn test() {
- let nthreads = 8u;
- let nmsgs = 1000u;
- let mut q = Queue::with_capacity(nthreads*nmsgs);
- assert_eq!(None, q.pop());
-
- for _ in range(0, nthreads) {
- let (port, chan) = comm::stream();
- chan.send(q.clone());
- do task::spawn_sched(task::SingleThreaded) {
- let mut q = port.recv();
- for i in range(0, nmsgs) {
- assert!(q.push(i));
- }
- }
- }
-
- let mut completion_ports = ~[];
- for _ in range(0, nthreads) {
- let (completion_port, completion_chan) = comm::stream();
- completion_ports.push(completion_port);
- let (port, chan) = comm::stream();
- chan.send(q.clone());
- do task::spawn_sched(task::SingleThreaded) {
- let mut q = port.recv();
- let mut i = 0u;
- loop {
- match q.pop() {
- None => {},
- Some(_) => {
- i += 1;
- if i == nmsgs { break }
- }
- }
- }
- completion_chan.send(i);
- }
- }
-
- for completion_port in completion_ports.iter() {
- assert_eq!(nmsgs, completion_port.recv());
- }
- }
-}
+++ /dev/null
-/* Multi-producer/single-consumer queue
- * Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-//! A mostly lock-free multi-producer, single consumer queue.
-// http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
-
-use unstable::sync::UnsafeArc;
-use unstable::atomics::{AtomicPtr,Relaxed,Release,Acquire};
-use ptr::{mut_null, to_mut_unsafe_ptr};
-use cast;
-use option::*;
-use clone::Clone;
-use kinds::Send;
-
-struct Node<T> {
- next: AtomicPtr<Node<T>>,
- value: Option<T>,
-}
-
-impl<T> Node<T> {
- fn empty() -> Node<T> {
- Node{next: AtomicPtr::new(mut_null()), value: None}
- }
-
- fn with_value(value: T) -> Node<T> {
- Node{next: AtomicPtr::new(mut_null()), value: Some(value)}
- }
-}
-
-struct State<T> {
- pad0: [u8, ..64],
- head: AtomicPtr<Node<T>>,
- pad1: [u8, ..64],
- stub: Node<T>,
- pad2: [u8, ..64],
- tail: *mut Node<T>,
- pad3: [u8, ..64],
-}
-
-struct Queue<T> {
- priv state: UnsafeArc<State<T>>,
-}
-
-impl<T: Send> Clone for Queue<T> {
- fn clone(&self) -> Queue<T> {
- Queue {
- state: self.state.clone()
- }
- }
-}
-
-impl<T: Send> State<T> {
- pub fn new() -> State<T> {
- State{
- pad0: [0, ..64],
- head: AtomicPtr::new(mut_null()),
- pad1: [0, ..64],
- stub: Node::<T>::empty(),
- pad2: [0, ..64],
- tail: mut_null(),
- pad3: [0, ..64],
- }
- }
-
- fn init(&mut self) {
- let stub = self.get_stub_unsafe();
- self.head.store(stub, Relaxed);
- self.tail = stub;
- }
-
- fn get_stub_unsafe(&mut self) -> *mut Node<T> {
- to_mut_unsafe_ptr(&mut self.stub)
- }
-
- fn push(&mut self, value: T) {
- unsafe {
- let node = cast::transmute(~Node::with_value(value));
- self.push_node(node);
- }
- }
-
- fn push_node(&mut self, node: *mut Node<T>) {
- unsafe {
- (*node).next.store(mut_null(), Release);
- let prev = self.head.swap(node, Relaxed);
- (*prev).next.store(node, Release);
- }
- }
-
- fn pop(&mut self) -> Option<T> {
- unsafe {
- let mut tail = self.tail;
- let mut next = (*tail).next.load(Acquire);
- let stub = self.get_stub_unsafe();
- if tail == stub {
- if mut_null() == next {
- return None
- }
- self.tail = next;
- tail = next;
- next = (*next).next.load(Acquire);
- }
- if next != mut_null() {
- let tail: ~Node<T> = cast::transmute(tail);
- self.tail = next;
- return tail.value
- }
- let head = self.head.load(Relaxed);
- if tail != head {
- return None
- }
- self.push_node(stub);
- next = (*tail).next.load(Acquire);
- if next != mut_null() {
- let tail: ~Node<T> = cast::transmute(tail);
- self.tail = next;
- return tail.value
- }
- }
- None
- }
-}
-
-impl<T: Send> Queue<T> {
- pub fn new() -> Queue<T> {
- unsafe {
- let q = Queue{state: UnsafeArc::new(State::new())};
- (*q.state.get()).init();
- q
- }
- }
-
- pub fn push(&mut self, value: T) {
- unsafe { (*self.state.get()).push(value) }
- }
-
- pub fn pop(&mut self) -> Option<T> {
- unsafe{ (*self.state.get()).pop() }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::*;
- use option::*;
- use task;
- use comm;
- use super::Queue;
-
- #[test]
- fn test() {
- let nthreads = 8u;
- let nmsgs = 1000u;
- let mut q = Queue::new();
- assert_eq!(None, q.pop());
-
- for _ in range(0, nthreads) {
- let (port, chan) = comm::stream();
- chan.send(q.clone());
- do task::spawn_sched(task::SingleThreaded) {
- let mut q = port.recv();
- for i in range(0, nmsgs) {
- q.push(i);
- }
- }
- }
-
- let mut i = 0u;
- loop {
- match q.pop() {
- None => {},
- Some(_) => {
- i += 1;
- if i == nthreads*nmsgs { break }
- }
- }
- }
- }
-}
-
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! An owned, task-local, reference counted type
-//!
-//! # Safety note
-//!
-//! XXX There is currently no type-system mechanism for enforcing that
-//! reference counted types are both allocated on the exchange heap
-//! and also non-sendable
-//!
-//! This doesn't prevent borrowing multiple aliasable mutable pointers
-
-use ops::Drop;
-use clone::Clone;
-use libc::c_void;
-use cast;
-
-pub struct RC<T> {
- priv p: *c_void // ~(uint, T)
-}
-
-impl<T> RC<T> {
- pub fn new(val: T) -> RC<T> {
- unsafe {
- let v = ~(1, val);
- let p: *c_void = cast::transmute(v);
- RC { p: p }
- }
- }
-
- fn get_mut_state(&mut self) -> *mut (uint, T) {
- unsafe {
- let p: &mut ~(uint, T) = cast::transmute(&mut self.p);
- let p: *mut (uint, T) = &mut **p;
- return p;
- }
- }
-
- fn get_state(&self) -> *(uint, T) {
- unsafe {
- let p: &~(uint, T) = cast::transmute(&self.p);
- let p: *(uint, T) = &**p;
- return p;
- }
- }
-
- pub fn unsafe_borrow_mut(&mut self) -> *mut T {
- unsafe {
- match *self.get_mut_state() {
- (_, ref mut p) => {
- let p: *mut T = p;
- return p;
- }
- }
- }
- }
-
- pub fn refcount(&self) -> uint {
- unsafe {
- match *self.get_state() {
- (count, _) => count
- }
- }
- }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for RC<T> {
- fn drop(&mut self) {
- assert!(self.refcount() > 0);
-
- unsafe {
- match *self.get_mut_state() {
- (ref mut count, _) => {
- *count = *count - 1
- }
- }
-
- if self.refcount() == 0 {
- let _: ~(uint, T) = cast::transmute(self.p);
- }
- }
- }
-}
-
-impl<T> Clone for RC<T> {
- fn clone(&self) -> RC<T> {
- unsafe {
- // XXX: Mutable clone
- let this: &mut RC<T> = cast::transmute_mut(self);
-
- match *this.get_mut_state() {
- (ref mut count, _) => {
- *count = *count + 1;
- }
- }
- }
-
- RC { p: self.p }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::RC;
-
- #[test]
- fn smoke_test() {
- unsafe {
- let mut v1 = RC::new(100);
- assert!(*v1.unsafe_borrow_mut() == 100);
- assert!(v1.refcount() == 1);
-
- let mut v2 = v1.clone();
- assert!(*v2.unsafe_borrow_mut() == 100);
- assert!(v2.refcount() == 2);
-
- *v2.unsafe_borrow_mut() = 200;
- assert!(*v2.unsafe_borrow_mut() == 200);
- assert!(*v1.unsafe_borrow_mut() == 200);
-
- let v3 = v2.clone();
- assert!(v3.refcount() == 3);
- {
- let _v1 = v1;
- let _v2 = v2;
- }
- assert!(v3.refcount() == 1);
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use c_str::CString;
-use comm::{SharedChan, PortOne, Port};
-use libc::c_int;
-use libc;
-use option::*;
-use path::Path;
-use result::*;
-
-use ai = io::net::addrinfo;
-use io::IoError;
-use io::net::ip::{IpAddr, SocketAddr};
-use io::process::{ProcessConfig, ProcessExit};
-use io::signal::Signum;
-use io::{FileMode, FileAccess, FileStat, FilePermission};
-use io::{SeekStyle};
-
-pub trait Callback {
- fn call(&mut self);
-}
-
-pub trait EventLoop {
- fn run(&mut self);
- fn callback(&mut self, proc());
- fn pausible_idle_callback(&mut self, ~Callback) -> ~PausibleIdleCallback;
- fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
-
- /// The asynchronous I/O services. Not all event loops may provide one
- // FIXME(#9382) this is an awful interface
- fn io<'a>(&'a mut self, f: |&'a mut IoFactory|);
-}
-
-pub trait RemoteCallback {
- /// Trigger the remote callback. Note that the number of times the
- /// callback is run is not guaranteed. All that is guaranteed is
- /// that, after calling 'fire', the callback will be called at
- /// least once, but multiple callbacks may be coalesced and
- /// callbacks may be called more often requested. Destruction also
- /// triggers the callback.
- fn fire(&mut self);
-}
-
-/// Data needed to make a successful open(2) call
-/// Using unix flag conventions for now, which happens to also be what's supported
-/// libuv (it does translation to windows under the hood).
-pub struct FileOpenConfig {
- /// Path to file to be opened
- path: Path,
- /// Flags for file access mode (as per open(2))
- flags: int,
- /// File creation mode, ignored unless O_CREAT is passed as part of flags
- priv mode: int
-}
-
-/// Description of what to do when a file handle is closed
-pub enum CloseBehavior {
- /// Do not close this handle when the object is destroyed
- DontClose,
- /// Synchronously close the handle, meaning that the task will block when
- /// the handle is destroyed until it has been fully closed.
- CloseSynchronously,
- /// Asynchronously closes a handle, meaning that the task will *not* block
- /// when the handle is destroyed, but the handle will still get deallocated
- /// and cleaned up (but this will happen asynchronously on the local event
- /// loop).
- CloseAsynchronously,
-}
-
-pub fn with_local_io<T>(f: |&mut IoFactory| -> Option<T>) -> Option<T> {
- use rt::sched::Scheduler;
- use rt::local::Local;
- use io::native;
-
- unsafe {
- // First, attempt to use the local scheduler's I/O services
- let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow();
- match sched {
- Some(sched) => {
- let mut io = None;
- (*sched).event_loop.io(|i| io = Some(i));
- match io {
- Some(io) => return f(io),
- None => {}
- }
- }
- None => {}
- }
- }
-
- // If we don't have a scheduler or the scheduler doesn't have I/O services,
- // then fall back to the native I/O services.
- let mut io = native::IoFactory;
- f(&mut io as &mut IoFactory)
-}
-
-pub trait IoFactory {
- // networking
- fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStream, IoError>;
- fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListener, IoError>;
- fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError>;
- fn unix_bind(&mut self, path: &CString) ->
- Result<~RtioUnixListener, IoError>;
- fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError>;
- fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
- hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError>;
-
- // filesystem operations
- fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream;
- fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
- -> Result<~RtioFileStream, IoError>;
- fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError>;
- fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError>;
- fn fs_mkdir(&mut self, path: &CString,
- mode: FilePermission) -> Result<(), IoError>;
- fn fs_chmod(&mut self, path: &CString,
- mode: FilePermission) -> Result<(), IoError>;
- fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError>;
- fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError>;
- fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
- Result<~[Path], IoError>;
- fn fs_lstat(&mut self, path: &CString) -> Result<FileStat, IoError>;
- fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
- Result<(), IoError>;
- fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError>;
- fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
- fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
- fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
- Result<(), IoError>;
-
- // misc
- fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
- fn spawn(&mut self, config: ProcessConfig)
- -> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>;
- fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError>;
- fn tty_open(&mut self, fd: c_int, readable: bool)
- -> Result<~RtioTTY, IoError>;
- fn signal(&mut self, signal: Signum, channel: SharedChan<Signum>)
- -> Result<~RtioSignal, IoError>;
-}
-
-pub trait RtioTcpListener : RtioSocket {
- fn listen(~self) -> Result<~RtioTcpAcceptor, IoError>;
-}
-
-pub trait RtioTcpAcceptor : RtioSocket {
- fn accept(&mut self) -> Result<~RtioTcpStream, IoError>;
- fn accept_simultaneously(&mut self) -> Result<(), IoError>;
- fn dont_accept_simultaneously(&mut self) -> Result<(), IoError>;
-}
-
-pub trait RtioTcpStream : RtioSocket {
- fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
- fn peer_name(&mut self) -> Result<SocketAddr, IoError>;
- fn control_congestion(&mut self) -> Result<(), IoError>;
- fn nodelay(&mut self) -> Result<(), IoError>;
- fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError>;
- fn letdie(&mut self) -> Result<(), IoError>;
-}
-
-pub trait RtioSocket {
- fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
-}
-
-pub trait RtioUdpSocket : RtioSocket {
- fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError>;
- fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError>;
-
- fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
- fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
-
- fn loop_multicast_locally(&mut self) -> Result<(), IoError>;
- fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError>;
-
- fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
- fn time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
-
- fn hear_broadcasts(&mut self) -> Result<(), IoError>;
- fn ignore_broadcasts(&mut self) -> Result<(), IoError>;
-}
-
-pub trait RtioTimer {
- fn sleep(&mut self, msecs: u64);
- fn oneshot(&mut self, msecs: u64) -> PortOne<()>;
- fn period(&mut self, msecs: u64) -> Port<()>;
-}
-
-pub trait RtioFileStream {
- fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError>;
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
- fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError>;
- fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError>;
- fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError>;
- fn tell(&self) -> Result<u64, IoError>;
- fn fsync(&mut self) -> Result<(), IoError>;
- fn datasync(&mut self) -> Result<(), IoError>;
- fn truncate(&mut self, offset: i64) -> Result<(), IoError>;
-}
-
-pub trait RtioProcess {
- fn id(&self) -> libc::pid_t;
- fn kill(&mut self, signal: int) -> Result<(), IoError>;
- fn wait(&mut self) -> ProcessExit;
-}
-
-pub trait RtioPipe {
- fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
-}
-
-pub trait RtioUnixListener {
- fn listen(~self) -> Result<~RtioUnixAcceptor, IoError>;
-}
-
-pub trait RtioUnixAcceptor {
- fn accept(&mut self) -> Result<~RtioPipe, IoError>;
-}
-
-pub trait RtioTTY {
- fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
- fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
- fn set_raw(&mut self, raw: bool) -> Result<(), IoError>;
- fn get_winsize(&mut self) -> Result<(int, int), IoError>;
- fn isatty(&self) -> bool;
-}
-
-pub trait PausibleIdleCallback {
- fn pause(&mut self);
- fn resume(&mut self);
-}
-
-pub trait RtioSignal {}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use option::{Option, Some, None};
-use cast::{transmute, transmute_mut_region, transmute_mut_unsafe};
-use clone::Clone;
-use unstable::raw;
-use super::sleeper_list::SleeperList;
-use super::work_queue::WorkQueue;
-use super::stack::{StackPool};
-use super::rtio::EventLoop;
-use super::context::Context;
-use super::task::{Task, AnySched, Sched};
-use super::message_queue::MessageQueue;
-use rt::kill::BlockedTask;
-use rt::local_ptr;
-use rt::local::Local;
-use rt::rtio::{RemoteCallback, PausibleIdleCallback, Callback};
-use borrow::{to_uint};
-use cell::Cell;
-use rand::{XorShiftRng, Rng, Rand};
-use iter::range;
-use vec::{OwnedVector};
-
-/// A scheduler is responsible for coordinating the execution of Tasks
-/// on a single thread. The scheduler runs inside a slightly modified
-/// Rust Task. When not running this task is stored in the scheduler
-/// struct. The scheduler struct acts like a baton, all scheduling
-/// actions are transfers of the baton.
-///
-/// XXX: This creates too many callbacks to run_sched_once, resulting
-/// in too much allocation and too many events.
-pub struct Scheduler {
- /// There are N work queues, one per scheduler.
- priv work_queue: WorkQueue<~Task>,
- /// Work queues for the other schedulers. These are created by
- /// cloning the core work queues.
- work_queues: ~[WorkQueue<~Task>],
- /// The queue of incoming messages from other schedulers.
- /// These are enqueued by SchedHandles after which a remote callback
- /// is triggered to handle the message.
- priv message_queue: MessageQueue<SchedMessage>,
- /// A shared list of sleeping schedulers. We'll use this to wake
- /// up schedulers when pushing work onto the work queue.
- sleeper_list: SleeperList,
- /// Indicates that we have previously pushed a handle onto the
- /// SleeperList but have not yet received the Wake message.
- /// Being `true` does not necessarily mean that the scheduler is
- /// not active since there are multiple event sources that may
- /// wake the scheduler. It just prevents the scheduler from pushing
- /// multiple handles onto the sleeper list.
- priv sleepy: bool,
- /// A flag to indicate we've received the shutdown message and should
- /// no longer try to go to sleep, but exit instead.
- no_sleep: bool,
- stack_pool: StackPool,
- /// The scheduler runs on a special task. When it is not running
- /// it is stored here instead of the work queue.
- priv sched_task: Option<~Task>,
- /// An action performed after a context switch on behalf of the
- /// code running before the context switch
- priv cleanup_job: Option<CleanupJob>,
- /// Should this scheduler run any task, or only pinned tasks?
- run_anything: bool,
- /// If the scheduler shouldn't run some tasks, a friend to send
- /// them to.
- priv friend_handle: Option<SchedHandle>,
- /// A fast XorShift rng for scheduler use
- rng: XorShiftRng,
- /// A toggleable idle callback
- priv idle_callback: Option<~PausibleIdleCallback>,
- /// A countdown that starts at a random value and is decremented
- /// every time a yield check is performed. When it hits 0 a task
- /// will yield.
- priv yield_check_count: uint,
- /// A flag to tell the scheduler loop it needs to do some stealing
- /// in order to introduce randomness as part of a yield
- priv steal_for_yield: bool,
-
- // n.b. currently destructors of an object are run in top-to-bottom in order
- // of field declaration. Due to its nature, the pausible idle callback
- // must have some sort of handle to the event loop, so it needs to get
- // destroyed before the event loop itself. For this reason, we destroy
- // the event loop last to ensure that any unsafe references to it are
- // destroyed before it's actually destroyed.
-
- /// The event loop used to drive the scheduler and perform I/O
- event_loop: ~EventLoop,
-}
-
-/// An indication of how hard to work on a given operation, the difference
-/// mainly being whether memory is synchronized or not
-#[deriving(Eq)]
-enum EffortLevel {
- DontTryTooHard,
- GiveItYourBest
-}
-
-static MAX_YIELD_CHECKS: uint = 200;
-
-fn reset_yield_check(rng: &mut XorShiftRng) -> uint {
- let r: uint = Rand::rand(rng);
- r % MAX_YIELD_CHECKS + 1
-}
-
-impl Scheduler {
-
- // * Initialization Functions
-
- pub fn new(event_loop: ~EventLoop,
- work_queue: WorkQueue<~Task>,
- work_queues: ~[WorkQueue<~Task>],
- sleeper_list: SleeperList)
- -> Scheduler {
-
- Scheduler::new_special(event_loop, work_queue,
- work_queues,
- sleeper_list, true, None)
-
- }
-
- pub fn new_special(event_loop: ~EventLoop,
- work_queue: WorkQueue<~Task>,
- work_queues: ~[WorkQueue<~Task>],
- sleeper_list: SleeperList,
- run_anything: bool,
- friend: Option<SchedHandle>)
- -> Scheduler {
-
- let mut sched = Scheduler {
- sleeper_list: sleeper_list,
- message_queue: MessageQueue::new(),
- sleepy: false,
- no_sleep: false,
- event_loop: event_loop,
- work_queue: work_queue,
- work_queues: work_queues,
- stack_pool: StackPool::new(),
- sched_task: None,
- cleanup_job: None,
- run_anything: run_anything,
- friend_handle: friend,
- rng: new_sched_rng(),
- idle_callback: None,
- yield_check_count: 0,
- steal_for_yield: false
- };
-
- sched.yield_check_count = reset_yield_check(&mut sched.rng);
-
- return sched;
- }
-
- // XXX: This may eventually need to be refactored so that
- // the scheduler itself doesn't have to call event_loop.run.
- // That will be important for embedding the runtime into external
- // event loops.
-
- // Take a main task to run, and a scheduler to run it in. Create a
- // scheduler task and bootstrap into it.
- pub fn bootstrap(mut ~self, task: ~Task) {
-
- // Build an Idle callback.
- let cb = ~SchedRunner as ~Callback;
- self.idle_callback = Some(self.event_loop.pausible_idle_callback(cb));
-
- // Initialize the TLS key.
- local_ptr::init();
-
- // Create a task for the scheduler with an empty context.
- let sched_task = ~Task::new_sched_task();
-
- // Now that we have an empty task struct for the scheduler
- // task, put it in TLS.
- Local::put(sched_task);
-
- // Before starting our first task, make sure the idle callback
- // is active. As we do not start in the sleep state this is
- // important.
- self.idle_callback.get_mut_ref().resume();
-
- // Now, as far as all the scheduler state is concerned, we are
- // inside the "scheduler" context. So we can act like the
- // scheduler and resume the provided task.
- self.resume_task_immediately(task);
-
- // Now we are back in the scheduler context, having
- // successfully run the input task. Start by running the
- // scheduler. Grab it out of TLS - performing the scheduler
- // action will have given it away.
- let sched: ~Scheduler = Local::take();
-
- rtdebug!("starting scheduler {}", sched.sched_id());
- sched.run();
-
- // Close the idle callback.
- let mut sched: ~Scheduler = Local::take();
- sched.idle_callback.take();
- // Make one go through the loop to run the close callback.
- sched.run();
-
- // Now that we are done with the scheduler, clean up the
- // scheduler task. Do so by removing it from TLS and manually
- // cleaning up the memory it uses. As we didn't actually call
- // task.run() on the scheduler task we never get through all
- // the cleanup code it runs.
- let mut stask: ~Task = Local::take();
-
- rtdebug!("stopping scheduler {}", stask.sched.get_ref().sched_id());
-
- // Should not have any messages
- let message = stask.sched.get_mut_ref().message_queue.pop();
- rtassert!(message.is_none());
-
- stask.destroyed = true;
- }
-
- // This does not return a scheduler, as the scheduler is placed
- // inside the task.
- pub fn run(mut ~self) {
-
- // This is unsafe because we need to place the scheduler, with
- // the event_loop inside, inside our task. But we still need a
- // mutable reference to the event_loop to give it the "run"
- // command.
- unsafe {
- let event_loop: *mut ~EventLoop = &mut self.event_loop;
-
- // Our scheduler must be in the task before the event loop
- // is started.
- let self_sched = Cell::new(self);
- Local::borrow(|stask: &mut Task| {
- stask.sched = Some(self_sched.take());
- });
-
- (*event_loop).run();
- }
- }
-
- // * Execution Functions - Core Loop Logic
-
- // The model for this function is that you continue through it
- // until you either use the scheduler while performing a schedule
- // action, in which case you give it away and return early, or
- // you reach the end and sleep. In the case that a scheduler
- // action is performed the loop is evented such that this function
- // is called again.
- fn run_sched_once() {
-
- // When we reach the scheduler context via the event loop we
- // already have a scheduler stored in our local task, so we
- // start off by taking it. This is the only path through the
- // scheduler where we get the scheduler this way.
- let mut sched: ~Scheduler = Local::take();
-
- // Assume that we need to continue idling unless we reach the
- // end of this function without performing an action.
- sched.idle_callback.get_mut_ref().resume();
-
- // First we check for scheduler messages, these are higher
- // priority than regular tasks.
- let sched = match sched.interpret_message_queue(DontTryTooHard) {
- Some(sched) => sched,
- None => return
- };
-
- // This helper will use a randomized work-stealing algorithm
- // to find work.
- let sched = match sched.do_work() {
- Some(sched) => sched,
- None => return
- };
-
- // Now, before sleeping we need to find out if there really
- // were any messages. Give it your best!
- let mut sched = match sched.interpret_message_queue(GiveItYourBest) {
- Some(sched) => sched,
- None => return
- };
-
- // If we got here then there was no work to do.
- // Generate a SchedHandle and push it to the sleeper list so
- // somebody can wake us up later.
- if !sched.sleepy && !sched.no_sleep {
- rtdebug!("scheduler has no work to do, going to sleep");
- sched.sleepy = true;
- let handle = sched.make_handle();
- sched.sleeper_list.push(handle);
- // Since we are sleeping, deactivate the idle callback.
- sched.idle_callback.get_mut_ref().pause();
- } else {
- rtdebug!("not sleeping, already doing so or no_sleep set");
- // We may not be sleeping, but we still need to deactivate
- // the idle callback.
- sched.idle_callback.get_mut_ref().pause();
- }
-
- // Finished a cycle without using the Scheduler. Place it back
- // in TLS.
- Local::put(sched);
- }
-
- // This function returns None if the scheduler is "used", or it
- // returns the still-available scheduler. At this point all
- // message-handling will count as a turn of work, and as a result
- // return None.
- fn interpret_message_queue(mut ~self, effort: EffortLevel) -> Option<~Scheduler> {
-
- let msg = if effort == DontTryTooHard {
- // Do a cheap check that may miss messages
- self.message_queue.casual_pop()
- } else {
- self.message_queue.pop()
- };
-
- match msg {
- Some(PinnedTask(task)) => {
- let mut task = task;
- task.give_home(Sched(self.make_handle()));
- self.resume_task_immediately(task);
- return None;
- }
- Some(TaskFromFriend(task)) => {
- rtdebug!("got a task from a friend. lovely!");
- self.process_task(task, Scheduler::resume_task_immediately_cl);
- return None;
- }
- Some(RunOnce(task)) => {
- // bypass the process_task logic to force running this task once
- // on this home scheduler. This is often used for I/O (homing).
- Scheduler::resume_task_immediately_cl(self, task);
- return None;
- }
- Some(Wake) => {
- self.sleepy = false;
- Local::put(self);
- return None;
- }
- Some(Shutdown) => {
- rtdebug!("shutting down");
- if self.sleepy {
- // There may be an outstanding handle on the
- // sleeper list. Pop them all to make sure that's
- // not the case.
- loop {
- match self.sleeper_list.pop() {
- Some(handle) => {
- let mut handle = handle;
- handle.send(Wake);
- }
- None => break
- }
- }
- }
- // No more sleeping. After there are no outstanding
- // event loop references we will shut down.
- self.no_sleep = true;
- self.sleepy = false;
- Local::put(self);
- return None;
- }
- None => {
- return Some(self);
- }
- }
- }
-
- fn do_work(mut ~self) -> Option<~Scheduler> {
- rtdebug!("scheduler calling do work");
- match self.find_work() {
- Some(task) => {
- rtdebug!("found some work! processing the task");
- self.process_task(task, Scheduler::resume_task_immediately_cl);
- return None;
- }
- None => {
- rtdebug!("no work was found, returning the scheduler struct");
- return Some(self);
- }
- }
- }
-
- // Workstealing: In this iteration of the runtime each scheduler
- // thread has a distinct work queue. When no work is available
- // locally, make a few attempts to steal work from the queues of
- // other scheduler threads. If a few steals fail we end up in the
- // old "no work" path which is fine.
-
- // First step in the process is to find a task. This function does
- // that by first checking the local queue, and if there is no work
- // there, trying to steal from the remote work queues.
- fn find_work(&mut self) -> Option<~Task> {
- rtdebug!("scheduler looking for work");
- if !self.steal_for_yield {
- match self.work_queue.pop() {
- Some(task) => {
- rtdebug!("found a task locally");
- return Some(task)
- }
- None => {
- rtdebug!("scheduler trying to steal");
- return self.try_steals();
- }
- }
- } else {
- // During execution of the last task, it performed a 'yield',
- // so we're doing some work stealing in order to introduce some
- // scheduling randomness. Otherwise we would just end up popping
- // that same task again. This is pretty lame and is to work around
- // the problem that work stealing is not designed for 'non-strict'
- // (non-fork-join) task parallelism.
- self.steal_for_yield = false;
- match self.try_steals() {
- Some(task) => {
- rtdebug!("stole a task after yielding");
- return Some(task);
- }
- None => {
- rtdebug!("did not steal a task after yielding");
- // Back to business
- return self.find_work();
- }
- }
- }
- }
-
- // Try stealing from all queues the scheduler knows about. This
- // naive implementation can steal from our own queue or from other
- // special schedulers.
- fn try_steals(&mut self) -> Option<~Task> {
- let work_queues = &mut self.work_queues;
- let len = work_queues.len();
- let start_index = self.rng.gen_range(0, len);
- for index in range(0, len).map(|i| (i + start_index) % len) {
- match work_queues[index].steal() {
- Some(task) => {
- rtdebug!("found task by stealing");
- return Some(task)
- }
- None => ()
- }
- };
- rtdebug!("giving up on stealing");
- return None;
- }
-
- // * Task Routing Functions - Make sure tasks send up in the right
- // place.
-
- fn process_task(mut ~self, mut task: ~Task, schedule_fn: SchedulingFn) {
- rtdebug!("processing a task");
-
- let home = task.take_unwrap_home();
- match home {
- Sched(home_handle) => {
- if home_handle.sched_id != self.sched_id() {
- rtdebug!("sending task home");
- task.give_home(Sched(home_handle));
- Scheduler::send_task_home(task);
- Local::put(self);
- } else {
- rtdebug!("running task here");
- task.give_home(Sched(home_handle));
- schedule_fn(self, task);
- }
- }
- AnySched if self.run_anything => {
- rtdebug!("running anysched task here");
- task.give_home(AnySched);
- schedule_fn(self, task);
- }
- AnySched => {
- rtdebug!("sending task to friend");
- task.give_home(AnySched);
- self.send_to_friend(task);
- Local::put(self);
- }
- }
- }
-
- fn send_task_home(task: ~Task) {
- let mut task = task;
- let mut home = task.take_unwrap_home();
- match home {
- Sched(ref mut home_handle) => {
- home_handle.send(PinnedTask(task));
- }
- AnySched => {
- rtabort!("error: cannot send anysched task home");
- }
- }
- }
-
- /// Take a non-homed task we aren't allowed to run here and send
- /// it to the designated friend scheduler to execute.
- fn send_to_friend(&mut self, task: ~Task) {
- rtdebug!("sending a task to friend");
- match self.friend_handle {
- Some(ref mut handle) => {
- handle.send(TaskFromFriend(task));
- }
- None => {
- rtabort!("tried to send task to a friend but scheduler has no friends");
- }
- }
- }
-
- /// Schedule a task to be executed later.
- ///
- /// Pushes the task onto the work stealing queue and tells the
- /// event loop to run it later. Always use this instead of pushing
- /// to the work queue directly.
- pub fn enqueue_task(&mut self, task: ~Task) {
-
- // We push the task onto our local queue clone.
- self.work_queue.push(task);
- self.idle_callback.get_mut_ref().resume();
-
- // We've made work available. Notify a
- // sleeping scheduler.
-
- match self.sleeper_list.casual_pop() {
- Some(handle) => {
- let mut handle = handle;
- handle.send(Wake)
- }
- None => { (/* pass */) }
- };
- }
-
- /// As enqueue_task, but with the possibility for the blocked task to
- /// already have been killed.
- pub fn enqueue_blocked_task(&mut self, blocked_task: BlockedTask) {
- blocked_task.wake().map(|task| self.enqueue_task(task));
- }
-
- // * Core Context Switching Functions
-
- // The primary function for changing contexts. In the current
- // design the scheduler is just a slightly modified GreenTask, so
- // all context swaps are from Task to Task. The only difference
- // between the various cases is where the inputs come from, and
- // what is done with the resulting task. That is specified by the
- // cleanup function f, which takes the scheduler and the
- // old task as inputs.
-
- pub fn change_task_context(mut ~self,
- next_task: ~Task,
- f: |&mut Scheduler, ~Task|) {
- // The current task is grabbed from TLS, not taken as an input.
- // Doing an unsafe_take to avoid writing back a null pointer -
- // We're going to call `put` later to do that.
- let current_task: ~Task = unsafe { Local::unsafe_take() };
-
- // Check that the task is not in an atomically() section (e.g.,
- // holding a pthread mutex, which could deadlock the scheduler).
- current_task.death.assert_may_sleep();
-
- // These transmutes do something fishy with a closure.
- let f_fake_region = unsafe {
- transmute::<|&mut Scheduler, ~Task|,
- |&mut Scheduler, ~Task|>(f)
- };
- let f_opaque = ClosureConverter::from_fn(f_fake_region);
-
- // The current task is placed inside an enum with the cleanup
- // function. This enum is then placed inside the scheduler.
- self.cleanup_job = Some(CleanupJob::new(current_task, f_opaque));
-
- // The scheduler is then placed inside the next task.
- let mut next_task = next_task;
- next_task.sched = Some(self);
-
- // However we still need an internal mutable pointer to the
- // original task. The strategy here was "arrange memory, then
- // get pointers", so we crawl back up the chain using
- // transmute to eliminate borrowck errors.
- unsafe {
-
- let sched: &mut Scheduler =
- transmute_mut_region(*next_task.sched.get_mut_ref());
-
- let current_task: &mut Task = match sched.cleanup_job {
- Some(CleanupJob { task: ref task, .. }) => {
- let task_ptr: *~Task = task;
- transmute_mut_region(*transmute_mut_unsafe(task_ptr))
- }
- None => {
- rtabort!("no cleanup job");
- }
- };
-
- let (current_task_context, next_task_context) =
- Scheduler::get_contexts(current_task, next_task);
-
- // Done with everything - put the next task in TLS. This
- // works because due to transmute the borrow checker
- // believes that we have no internal pointers to
- // next_task.
- Local::put(next_task);
-
- // The raw context swap operation. The next action taken
- // will be running the cleanup job from the context of the
- // next task.
- Context::swap(current_task_context, next_task_context);
- }
-
- // When the context swaps back to this task we immediately
- // run the cleanup job, as expected by the previously called
- // swap_contexts function.
- unsafe {
- let task: *mut Task = Local::unsafe_borrow();
- (*task).sched.get_mut_ref().run_cleanup_job();
- }
- }
-
- // Returns a mutable reference to both contexts involved in this
- // swap. This is unsafe - we are getting mutable internal
- // references to keep even when we don't own the tasks. It looks
- // kinda safe because we are doing transmutes before passing in
- // the arguments.
- pub fn get_contexts<'a>(current_task: &mut Task, next_task: &mut Task) ->
- (&'a mut Context, &'a mut Context) {
- let current_task_context =
- &mut current_task.coroutine.get_mut_ref().saved_context;
- let next_task_context =
- &mut next_task.coroutine.get_mut_ref().saved_context;
- unsafe {
- (transmute_mut_region(current_task_context),
- transmute_mut_region(next_task_context))
- }
- }
-
- // * Context Swapping Helpers - Here be ugliness!
-
- pub fn resume_task_immediately(~self, task: ~Task) {
- self.change_task_context(task, |sched, stask| {
- sched.sched_task = Some(stask);
- })
- }
-
- fn resume_task_immediately_cl(sched: ~Scheduler,
- task: ~Task) {
- sched.resume_task_immediately(task)
- }
-
-
- pub fn resume_blocked_task_immediately(~self, blocked_task: BlockedTask) {
- match blocked_task.wake() {
- Some(task) => { self.resume_task_immediately(task); }
- None => Local::put(self)
- };
- }
-
- /// Block a running task, context switch to the scheduler, then pass the
- /// blocked task to a closure.
- ///
- /// # Safety note
- ///
- /// The closure here is a *stack* closure that lives in the
- /// running task. It gets transmuted to the scheduler's lifetime
- /// and called while the task is blocked.
- ///
- /// This passes a Scheduler pointer to the fn after the context switch
- /// in order to prevent that fn from performing further scheduling operations.
- /// Doing further scheduling could easily result in infinite recursion.
- pub fn deschedule_running_task_and_then(mut ~self,
- f: |&mut Scheduler, BlockedTask|) {
- // Trickier - we need to get the scheduler task out of self
- // and use it as the destination.
- let stask = self.sched_task.take_unwrap();
- // Otherwise this is the same as below.
- self.switch_running_tasks_and_then(stask, f);
- }
-
- pub fn switch_running_tasks_and_then(~self, next_task: ~Task,
- f: |&mut Scheduler, BlockedTask|) {
- // This is where we convert the BlockedTask-taking closure into one
- // that takes just a Task
- self.change_task_context(next_task, |sched, task| {
- f(sched, BlockedTask::block(task))
- })
- }
-
- fn switch_task(sched: ~Scheduler, task: ~Task) {
- sched.switch_running_tasks_and_then(task, |sched, last_task| {
- sched.enqueue_blocked_task(last_task);
- });
- }
-
- // * Task Context Helpers
-
- /// Called by a running task to end execution, after which it will
- /// be recycled by the scheduler for reuse in a new task.
- pub fn terminate_current_task(mut ~self) {
- // Similar to deschedule running task and then, but cannot go through
- // the task-blocking path. The task is already dying.
- let stask = self.sched_task.take_unwrap();
- self.change_task_context(stask, |sched, mut dead_task| {
- let coroutine = dead_task.coroutine.take_unwrap();
- coroutine.recycle(&mut sched.stack_pool);
- })
- }
-
- pub fn run_task(task: ~Task) {
- let sched: ~Scheduler = Local::take();
- sched.process_task(task, Scheduler::switch_task);
- }
-
- pub fn run_task_later(next_task: ~Task) {
- let next_task = Cell::new(next_task);
- Local::borrow(|sched: &mut Scheduler| {
- sched.enqueue_task(next_task.take());
- });
- }
-
- /// Yield control to the scheduler, executing another task. This is guaranteed
- /// to introduce some amount of randomness to the scheduler. Currently the
- /// randomness is a result of performing a round of work stealing (which
- /// may end up stealing from the current scheduler).
- pub fn yield_now(mut ~self) {
- self.yield_check_count = reset_yield_check(&mut self.rng);
- // Tell the scheduler to start stealing on the next iteration
- self.steal_for_yield = true;
- self.deschedule_running_task_and_then(|sched, task| {
- sched.enqueue_blocked_task(task);
- })
- }
-
- pub fn maybe_yield(mut ~self) {
- // The number of times to do the yield check before yielding, chosen arbitrarily.
- rtassert!(self.yield_check_count > 0);
- self.yield_check_count -= 1;
- if self.yield_check_count == 0 {
- self.yield_now();
- } else {
- Local::put(self);
- }
- }
-
-
- // * Utility Functions
-
- pub fn sched_id(&self) -> uint { to_uint(self) }
-
- pub fn run_cleanup_job(&mut self) {
- let cleanup_job = self.cleanup_job.take_unwrap();
- cleanup_job.run(self);
- }
-
- pub fn make_handle(&mut self) -> SchedHandle {
- let remote = self.event_loop.remote_callback(~SchedRunner as ~Callback);
-
- return SchedHandle {
- remote: remote,
- queue: self.message_queue.clone(),
- sched_id: self.sched_id()
- };
- }
-}
-
-// Supporting types
-
-type SchedulingFn = extern "Rust" fn (~Scheduler, ~Task);
-
-pub enum SchedMessage {
- Wake,
- Shutdown,
- PinnedTask(~Task),
- TaskFromFriend(~Task),
- RunOnce(~Task),
-}
-
-pub struct SchedHandle {
- priv remote: ~RemoteCallback,
- priv queue: MessageQueue<SchedMessage>,
- sched_id: uint
-}
-
-impl SchedHandle {
- pub fn send(&mut self, msg: SchedMessage) {
- self.queue.push(msg);
- self.remote.fire();
- }
-}
-
-struct SchedRunner;
-
-impl Callback for SchedRunner {
- fn call(&mut self) {
- Scheduler::run_sched_once();
- }
-}
-
-struct CleanupJob {
- task: ~Task,
- f: UnsafeTaskReceiver
-}
-
-impl CleanupJob {
- pub fn new(task: ~Task, f: UnsafeTaskReceiver) -> CleanupJob {
- CleanupJob {
- task: task,
- f: f
- }
- }
-
- pub fn run(self, sched: &mut Scheduler) {
- let CleanupJob { task: task, f: f } = self;
- f.to_fn()(sched, task)
- }
-}
-
-// XXX: Some hacks to put a || closure in Scheduler without borrowck
-// complaining
-type UnsafeTaskReceiver = raw::Closure;
-trait ClosureConverter {
- fn from_fn(|&mut Scheduler, ~Task|) -> Self;
- fn to_fn(self) -> |&mut Scheduler, ~Task|;
-}
-impl ClosureConverter for UnsafeTaskReceiver {
- fn from_fn(f: |&mut Scheduler, ~Task|) -> UnsafeTaskReceiver {
- unsafe { transmute(f) }
- }
- fn to_fn(self) -> |&mut Scheduler, ~Task| { unsafe { transmute(self) } }
-}
-
-// On unix, we read randomness straight from /dev/urandom, but the
-// default constructor of an XorShiftRng does this via io::fs, which
-// relies on the scheduler existing, so we have to manually load
-// randomness. Windows has its own C API for this, so we don't need to
-// worry there.
-#[cfg(windows)]
-fn new_sched_rng() -> XorShiftRng {
- XorShiftRng::new()
-}
-#[cfg(unix)]
-fn new_sched_rng() -> XorShiftRng {
- use libc;
- use mem;
- use c_str::ToCStr;
- use vec::MutableVector;
- use iter::Iterator;
- use rand::SeedableRng;
-
- let fd = "/dev/urandom".with_c_str(|name| {
- unsafe { libc::open(name, libc::O_RDONLY, 0) }
- });
- if fd == -1 {
- rtabort!("could not open /dev/urandom for reading.")
- }
-
- let mut seeds = [0u32, .. 4];
- let size = mem::size_of_val(&seeds);
- loop {
- let nbytes = seeds.as_mut_buf(|buf, _| {
- unsafe {
- libc::read(fd,
- buf as *mut libc::c_void,
- size as libc::size_t)
- }
- });
- rtassert!(nbytes as uint == size);
-
- if !seeds.iter().all(|x| *x == 0) {
- break;
- }
- }
-
- unsafe {libc::close(fd);}
-
- SeedableRng::from_seed(seeds)
-}
-
-#[cfg(test)]
-mod test {
- extern mod extra;
-
- use prelude::*;
- use rt::test::*;
- use unstable::run_in_bare_thread;
- use borrow::to_uint;
- use rt::sched::{Scheduler};
- use cell::Cell;
- use rt::thread::Thread;
- use rt::task::{Task, Sched};
- use rt::basic;
- use rt::util;
- use option::{Some};
- use rt::task::UnwindResult;
-
- #[test]
- fn trivial_run_in_newsched_task_test() {
- let mut task_ran = false;
- let task_ran_ptr: *mut bool = &mut task_ran;
- do run_in_newsched_task || {
- unsafe { *task_ran_ptr = true };
- rtdebug!("executed from the new scheduler")
- }
- assert!(task_ran);
- }
-
- #[test]
- fn multiple_task_test() {
- let total = 10;
- let mut task_run_count = 0;
- let task_run_count_ptr: *mut uint = &mut task_run_count;
- do run_in_newsched_task || {
- for _ in range(0u, total) {
- do spawntask || {
- unsafe { *task_run_count_ptr = *task_run_count_ptr + 1};
- }
- }
- }
- assert!(task_run_count == total);
- }
-
- #[test]
- fn multiple_task_nested_test() {
- let mut task_run_count = 0;
- let task_run_count_ptr: *mut uint = &mut task_run_count;
- do run_in_newsched_task || {
- do spawntask || {
- unsafe { *task_run_count_ptr = *task_run_count_ptr + 1 };
- do spawntask || {
- unsafe { *task_run_count_ptr = *task_run_count_ptr + 1 };
- do spawntask || {
- unsafe { *task_run_count_ptr = *task_run_count_ptr + 1 };
- }
- }
- }
- }
- assert!(task_run_count == 3);
- }
-
- // Confirm that a sched_id actually is the uint form of the
- // pointer to the scheduler struct.
- #[test]
- fn simple_sched_id_test() {
- do run_in_bare_thread {
- let sched = ~new_test_uv_sched();
- assert!(to_uint(sched) == sched.sched_id());
- }
- }
-
- // Compare two scheduler ids that are different, this should never
- // fail but may catch a mistake someday.
- #[test]
- fn compare_sched_id_test() {
- do run_in_bare_thread {
- let sched_one = ~new_test_uv_sched();
- let sched_two = ~new_test_uv_sched();
- assert!(sched_one.sched_id() != sched_two.sched_id());
- }
- }
-
-
- // A very simple test that confirms that a task executing on the
- // home scheduler notices that it is home.
- #[test]
- fn test_home_sched() {
- do run_in_bare_thread {
- let mut task_ran = false;
- let task_ran_ptr: *mut bool = &mut task_ran;
-
- let mut sched = ~new_test_uv_sched();
- let sched_handle = sched.make_handle();
-
- let mut task = ~do Task::new_root_homed(&mut sched.stack_pool, None,
- Sched(sched_handle)) {
- unsafe { *task_ran_ptr = true };
- assert!(Task::on_appropriate_sched());
- };
-
- let on_exit: proc(UnwindResult) = proc(exit_status) {
- rtassert!(exit_status.is_success())
- };
- task.death.on_exit = Some(on_exit);
-
- sched.bootstrap(task);
- }
- }
-
- // An advanced test that checks all four possible states that a
- // (task,sched) can be in regarding homes.
-
- #[test]
- fn test_schedule_home_states() {
- use rt::sleeper_list::SleeperList;
- use rt::work_queue::WorkQueue;
- use rt::sched::Shutdown;
- use borrow;
- use rt::comm::*;
-
- do run_in_bare_thread {
-
- let sleepers = SleeperList::new();
- let normal_queue = WorkQueue::new();
- let special_queue = WorkQueue::new();
- let queues = ~[normal_queue.clone(), special_queue.clone()];
-
- // Our normal scheduler
- let mut normal_sched = ~Scheduler::new(
- basic::event_loop(),
- normal_queue,
- queues.clone(),
- sleepers.clone());
-
- let normal_handle = Cell::new(normal_sched.make_handle());
-
- let friend_handle = normal_sched.make_handle();
-
- // Our special scheduler
- let mut special_sched = ~Scheduler::new_special(
- basic::event_loop(),
- special_queue.clone(),
- queues.clone(),
- sleepers.clone(),
- false,
- Some(friend_handle));
-
- let special_handle = Cell::new(special_sched.make_handle());
-
- let t1_handle = special_sched.make_handle();
- let t4_handle = special_sched.make_handle();
-
- // Four test tasks:
- // 1) task is home on special
- // 2) task not homed, sched doesn't care
- // 3) task not homed, sched requeues
- // 4) task not home, send home
-
- let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
- Sched(t1_handle)) || {
- rtassert!(Task::on_appropriate_sched());
- };
- rtdebug!("task1 id: **{}**", borrow::to_uint(task1));
-
- let task2 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
- rtassert!(Task::on_appropriate_sched());
- };
-
- let task3 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
- rtassert!(Task::on_appropriate_sched());
- };
-
- let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
- Sched(t4_handle)) {
- rtassert!(Task::on_appropriate_sched());
- };
- rtdebug!("task4 id: **{}**", borrow::to_uint(task4));
-
- let task1 = Cell::new(task1);
- let task2 = Cell::new(task2);
- let task3 = Cell::new(task3);
- let task4 = Cell::new(task4);
-
- // Signal from the special task that we are done.
- let (port, chan) = oneshot::<()>();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
- rtdebug!("*about to submit task2*");
- Scheduler::run_task(task2.take());
- rtdebug!("*about to submit task4*");
- Scheduler::run_task(task4.take());
- rtdebug!("*normal_task done*");
- port.take().recv();
- let mut nh = normal_handle.take();
- nh.send(Shutdown);
- let mut sh = special_handle.take();
- sh.send(Shutdown);
- };
-
- rtdebug!("normal task: {}", borrow::to_uint(normal_task));
-
- let special_task = ~do Task::new_root(&mut special_sched.stack_pool, None) {
- rtdebug!("*about to submit task1*");
- Scheduler::run_task(task1.take());
- rtdebug!("*about to submit task3*");
- Scheduler::run_task(task3.take());
- rtdebug!("*done with special_task*");
- chan.take().send(());
- };
-
- rtdebug!("special task: {}", borrow::to_uint(special_task));
-
- let special_sched = Cell::new(special_sched);
- let normal_sched = Cell::new(normal_sched);
- let special_task = Cell::new(special_task);
- let normal_task = Cell::new(normal_task);
-
- let normal_thread = do Thread::start {
- normal_sched.take().bootstrap(normal_task.take());
- rtdebug!("finished with normal_thread");
- };
-
- let special_thread = do Thread::start {
- special_sched.take().bootstrap(special_task.take());
- rtdebug!("finished with special_sched");
- };
-
- normal_thread.join();
- special_thread.join();
- }
- }
-
- #[test]
- fn test_stress_schedule_task_states() {
- if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
- let n = stress_factor() * 120;
- for _ in range(0, n as int) {
- test_schedule_home_states();
- }
- }
-
- #[test]
- fn test_io_callback() {
- use io::timer;
-
- // This is a regression test that when there are no schedulable tasks
- // in the work queue, but we are performing I/O, that once we do put
- // something in the work queue again the scheduler picks it up and doesn't
- // exit before emptying the work queue
- do run_in_uv_task {
- do spawntask {
- timer::sleep(10);
- }
- }
- }
-
- #[test]
- fn handle() {
- use rt::comm::*;
-
- do run_in_bare_thread {
- let (port, chan) = oneshot::<()>();
- let port = Cell::new(port);
- let chan = Cell::new(chan);
-
- let thread_one = do Thread::start {
- let chan = Cell::new(chan.take());
- do run_in_newsched_task_core {
- chan.take().send(());
- }
- };
-
- let thread_two = do Thread::start {
- let port = Cell::new(port.take());
- do run_in_newsched_task_core {
- port.take().recv();
- }
- };
-
- thread_two.join();
- thread_one.join();
- }
- }
-
- // A regression test that the final message is always handled.
- // Used to deadlock because Shutdown was never recvd.
- #[test]
- fn no_missed_messages() {
- use rt::work_queue::WorkQueue;
- use rt::sleeper_list::SleeperList;
- use rt::stack::StackPool;
- use rt::sched::{Shutdown, TaskFromFriend};
- use util;
-
- do run_in_bare_thread {
- stress_factor().times(|| {
- let sleepers = SleeperList::new();
- let queue = WorkQueue::new();
- let queues = ~[queue.clone()];
-
- let mut sched = ~Scheduler::new(
- basic::event_loop(),
- queue,
- queues.clone(),
- sleepers.clone());
-
- let mut handle = sched.make_handle();
-
- let sched = Cell::new(sched);
-
- let thread = do Thread::start {
- let mut sched = sched.take();
- let bootstrap_task =
- ~Task::new_root(&mut sched.stack_pool,
- None,
- proc()());
- sched.bootstrap(bootstrap_task);
- };
-
- let mut stack_pool = StackPool::new();
- let task = ~Task::new_root(&mut stack_pool, None, proc()());
- handle.send(TaskFromFriend(task));
-
- handle.send(Shutdown);
- util::ignore(handle);
-
- thread.join();
- })
- }
- }
-
- #[test]
- fn multithreading() {
- use rt::comm::*;
- use num::Times;
- use vec::OwnedVector;
- use container::Container;
-
- do run_in_mt_newsched_task {
- let mut ports = ~[];
- 10.times(|| {
- let (port, chan) = oneshot();
- let chan_cell = Cell::new(chan);
- do spawntask_later {
- chan_cell.take().send(());
- }
- ports.push(port);
- });
-
- while !ports.is_empty() {
- ports.pop().recv();
- }
- }
- }
-
- #[test]
- fn thread_ring() {
- use rt::comm::*;
- use comm::{GenericPort, GenericChan};
-
- do run_in_mt_newsched_task {
- let (end_port, end_chan) = oneshot();
-
- let n_tasks = 10;
- let token = 2000;
-
- let (p, ch1) = stream();
- let mut p = p;
- ch1.send((token, end_chan));
- let mut i = 2;
- while i <= n_tasks {
- let (next_p, ch) = stream();
- let imm_i = i;
- let imm_p = p;
- do spawntask_random {
- roundtrip(imm_i, n_tasks, &imm_p, &ch);
- };
- p = next_p;
- i += 1;
- }
- let imm_p = p;
- let imm_ch = ch1;
- do spawntask_random {
- roundtrip(1, n_tasks, &imm_p, &imm_ch);
- }
-
- end_port.recv();
- }
-
- fn roundtrip(id: int, n_tasks: int,
- p: &Port<(int, ChanOne<()>)>, ch: &Chan<(int, ChanOne<()>)>) {
- while (true) {
- match p.recv() {
- (1, end_chan) => {
- debug!("{}\n", id);
- end_chan.send(());
- return;
- }
- (token, end_chan) => {
- debug!("thread: {} got token: {}", id, token);
- ch.send((token - 1, end_chan));
- if token <= n_tasks {
- return;
- }
- }
- }
- }
- }
- }
-
- #[test]
- fn start_closure_dtor() {
- use ops::Drop;
-
- // Regression test that the `start` task entrypoint can
- // contain dtors that use task resources
- do run_in_newsched_task {
- struct S { field: () }
-
- impl Drop for S {
- fn drop(&mut self) {
- let _foo = @0;
- }
- }
-
- let s = S { field: () };
-
- do spawntask {
- let _ss = &s;
- }
- }
- }
-
- // FIXME: #9407: xfail-test
- fn dont_starve_1() {
- use rt::comm::oneshot;
-
- stress_factor().times(|| {
- do run_in_mt_newsched_task {
- let (port, chan) = oneshot();
-
- // This task should not be able to starve the sender;
- // The sender should get stolen to another thread.
- do spawntask {
- while !port.peek() { }
- }
-
- chan.send(());
- }
- })
- }
-
- #[test]
- fn dont_starve_2() {
- use rt::comm::oneshot;
-
- stress_factor().times(|| {
- do run_in_newsched_task {
- let (port, chan) = oneshot();
- let (_port2, chan2) = stream();
-
- // This task should not be able to starve the other task.
- // The sends should eventually yield.
- do spawntask {
- while !port.peek() {
- chan2.send(());
- }
- }
-
- chan.send(());
- }
- })
- }
-
- // Regression test for a logic bug that would cause single-threaded schedulers
- // to sleep forever after yielding and stealing another task.
- #[test]
- fn single_threaded_yield() {
- use task::{spawn, spawn_sched, SingleThreaded, deschedule};
- use num::Times;
-
- do spawn_sched(SingleThreaded) {
- 5.times(|| { deschedule(); })
- }
- do spawn { }
- do spawn { }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Module for private, abstraction-leaking select traits. Wrapped in std::select.
-
-use rt::kill::BlockedTask;
-use rt::sched::Scheduler;
-use option::Option;
-
-pub trait SelectInner {
- // Returns true if data was available.
- fn optimistic_check(&mut self) -> bool;
- // Returns true if data was available. If so, shall also wake() the task.
- fn block_on(&mut self, &mut Scheduler, BlockedTask) -> bool;
- // Returns true if data was available.
- fn unblock_from(&mut self) -> bool;
-}
-
-pub trait SelectPortInner<T> {
- fn recv_ready(self) -> Option<T>;
-}
-
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Maintains a shared list of sleeping schedulers. Schedulers
-//! use this to wake each other up.
-
-use rt::sched::SchedHandle;
-use rt::mpmc_bounded_queue::Queue;
-use option::*;
-use clone::Clone;
-
-pub struct SleeperList {
- priv q: Queue<SchedHandle>,
-}
-
-impl SleeperList {
- pub fn new() -> SleeperList {
- SleeperList{q: Queue::with_capacity(8*1024)}
- }
-
- pub fn push(&mut self, value: SchedHandle) {
- assert!(self.q.push(value))
- }
-
- pub fn pop(&mut self) -> Option<SchedHandle> {
- self.q.pop()
- }
-
- pub fn casual_pop(&mut self) -> Option<SchedHandle> {
- self.q.pop()
- }
-}
-
-impl Clone for SleeperList {
- fn clone(&self) -> SleeperList {
- SleeperList {
- q: self.q.clone()
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::Container;
-use ptr::RawPtr;
-use vec;
-use ops::Drop;
-use libc::{c_uint, uintptr_t};
-
-pub struct StackSegment {
- priv buf: ~[u8],
- priv valgrind_id: c_uint
-}
-
-impl StackSegment {
- pub fn new(size: uint) -> StackSegment {
- unsafe {
- // Crate a block of uninitialized values
- let mut stack = vec::with_capacity(size);
- vec::raw::set_len(&mut stack, size);
-
- let mut stk = StackSegment {
- buf: stack,
- valgrind_id: 0
- };
-
- // XXX: Using the FFI to call a C macro. Slow
- stk.valgrind_id = rust_valgrind_stack_register(stk.start(), stk.end());
- return stk;
- }
- }
-
- /// Point to the low end of the allocated stack
- pub fn start(&self) -> *uint {
- vec::raw::to_ptr(self.buf) as *uint
- }
-
- /// Point one word beyond the high end of the allocated stack
- pub fn end(&self) -> *uint {
- unsafe {
- vec::raw::to_ptr(self.buf).offset(self.buf.len() as int) as *uint
- }
- }
-}
-
-impl Drop for StackSegment {
- fn drop(&mut self) {
- unsafe {
- // XXX: Using the FFI to call a C macro. Slow
- rust_valgrind_stack_deregister(self.valgrind_id);
- }
- }
-}
-
-pub struct StackPool(());
-
-impl StackPool {
- pub fn new() -> StackPool { StackPool(()) }
-
- fn take_segment(&self, min_size: uint) -> StackSegment {
- StackSegment::new(min_size)
- }
-
- fn give_segment(&self, _stack: StackSegment) {
- }
-}
-
-extern {
- fn rust_valgrind_stack_register(start: *uintptr_t, end: *uintptr_t) -> c_uint;
- fn rust_valgrind_stack_deregister(id: c_uint);
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Language-level runtime services that should reasonably expected
-//! to be available 'everywhere'. Local heaps, GC, unwinding,
-//! local storage, and logging. Even a 'freestanding' Rust would likely want
-//! to implement this.
-
-use super::local_heap::LocalHeap;
-
-use prelude::*;
-
-use borrow;
-use cast::transmute;
-use cell::Cell;
-use cleanup;
-use libc::{c_void, uintptr_t, c_char, size_t};
-use local_data;
-use option::{Option, Some, None};
-use rt::borrowck::BorrowRecord;
-use rt::borrowck;
-use rt::context::Context;
-use rt::context;
-use rt::env;
-use io::Writer;
-use rt::kill::Death;
-use rt::local::Local;
-use rt::logging::StdErrLogger;
-use rt::sched::{Scheduler, SchedHandle};
-use rt::stack::{StackSegment, StackPool};
-use send_str::SendStr;
-use unstable::finally::Finally;
-
-// The Task struct represents all state associated with a rust
-// task. There are at this point two primary "subtypes" of task,
-// however instead of using a subtype we just have a "task_type" field
-// in the struct. This contains a pointer to another struct that holds
-// the type-specific state.
-
-pub struct Task {
- heap: LocalHeap,
- priv gc: GarbageCollector,
- storage: LocalStorage,
- logger: Option<StdErrLogger>,
- unwinder: Unwinder,
- death: Death,
- destroyed: bool,
- name: Option<SendStr>,
- coroutine: Option<Coroutine>,
- sched: Option<~Scheduler>,
- task_type: TaskType,
- // Dynamic borrowck debugging info
- borrow_list: Option<~[BorrowRecord]>,
- stdout_handle: Option<~Writer>,
-}
-
-pub enum TaskType {
- GreenTask(Option<SchedHome>),
- SchedTask
-}
-
-/// A coroutine is nothing more than a (register context, stack) pair.
-pub struct Coroutine {
- /// The segment of stack on which the task is currently running or
- /// if the task is blocked, on which the task will resume
- /// execution.
- ///
- /// Servo needs this to be public in order to tell SpiderMonkey
- /// about the stack bounds.
- current_stack_segment: StackSegment,
- /// Always valid if the task is alive and not running.
- saved_context: Context
-}
-
-/// Some tasks have a dedicated home scheduler that they must run on.
-pub enum SchedHome {
- AnySched,
- Sched(SchedHandle)
-}
-
-pub struct GarbageCollector;
-pub struct LocalStorage(Option<local_data::Map>);
-
-/// Represents the reason for the current unwinding process
-pub enum UnwindResult {
- /// The task is ending successfully
- Success,
-
- /// The Task is failing with reason `~Any`
- Failure(~Any),
-}
-
-impl UnwindResult {
- /// Returns `true` if this `UnwindResult` is a failure
- #[inline]
- pub fn is_failure(&self) -> bool {
- match *self {
- Success => false,
- Failure(_) => true
- }
- }
-
- /// Returns `true` if this `UnwindResult` is a success
- #[inline]
- pub fn is_success(&self) -> bool {
- match *self {
- Success => true,
- Failure(_) => false
- }
- }
-}
-
-pub struct Unwinder {
- unwinding: bool,
- cause: Option<~Any>
-}
-
-impl Unwinder {
- fn to_unwind_result(&mut self) -> UnwindResult {
- if self.unwinding {
- Failure(self.cause.take().unwrap())
- } else {
- Success
- }
- }
-}
-
-impl Task {
-
- // A helper to build a new task using the dynamically found
- // scheduler and task. Only works in GreenTask context.
- pub fn build_homed_child(stack_size: Option<uint>,
- f: proc(),
- home: SchedHome)
- -> ~Task {
- let f = Cell::new(f);
- let home = Cell::new(home);
- Local::borrow(|running_task: &mut Task| {
- let mut sched = running_task.sched.take_unwrap();
- let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
- stack_size,
- home.take(),
- f.take());
- running_task.sched = Some(sched);
- new_task
- })
- }
-
- pub fn build_child(stack_size: Option<uint>, f: proc()) -> ~Task {
- Task::build_homed_child(stack_size, f, AnySched)
- }
-
- pub fn build_homed_root(stack_size: Option<uint>,
- f: proc(),
- home: SchedHome)
- -> ~Task {
- let f = Cell::new(f);
- let home = Cell::new(home);
- Local::borrow(|running_task: &mut Task| {
- let mut sched = running_task.sched.take_unwrap();
- let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
- stack_size,
- home.take(),
- f.take());
- running_task.sched = Some(sched);
- new_task
- })
- }
-
- pub fn build_root(stack_size: Option<uint>, f: proc()) -> ~Task {
- Task::build_homed_root(stack_size, f, AnySched)
- }
-
- pub fn new_sched_task() -> Task {
- Task {
- heap: LocalHeap::new(),
- gc: GarbageCollector,
- storage: LocalStorage(None),
- logger: None,
- unwinder: Unwinder { unwinding: false, cause: None },
- death: Death::new(),
- destroyed: false,
- coroutine: Some(Coroutine::empty()),
- name: None,
- sched: None,
- task_type: SchedTask,
- borrow_list: None,
- stdout_handle: None,
- }
- }
-
- pub fn new_root(stack_pool: &mut StackPool,
- stack_size: Option<uint>,
- start: proc()) -> Task {
- Task::new_root_homed(stack_pool, stack_size, AnySched, start)
- }
-
- pub fn new_child(&mut self,
- stack_pool: &mut StackPool,
- stack_size: Option<uint>,
- start: proc()) -> Task {
- self.new_child_homed(stack_pool, stack_size, AnySched, start)
- }
-
- pub fn new_root_homed(stack_pool: &mut StackPool,
- stack_size: Option<uint>,
- home: SchedHome,
- start: proc()) -> Task {
- Task {
- heap: LocalHeap::new(),
- gc: GarbageCollector,
- storage: LocalStorage(None),
- logger: None,
- unwinder: Unwinder { unwinding: false, cause: None },
- death: Death::new(),
- destroyed: false,
- name: None,
- coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
- sched: None,
- task_type: GreenTask(Some(home)),
- borrow_list: None,
- stdout_handle: None,
- }
- }
-
- pub fn new_child_homed(&mut self,
- stack_pool: &mut StackPool,
- stack_size: Option<uint>,
- home: SchedHome,
- start: proc()) -> Task {
- Task {
- heap: LocalHeap::new(),
- gc: GarbageCollector,
- storage: LocalStorage(None),
- logger: None,
- unwinder: Unwinder { unwinding: false, cause: None },
- death: Death::new(),
- destroyed: false,
- name: None,
- coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
- sched: None,
- task_type: GreenTask(Some(home)),
- borrow_list: None,
- stdout_handle: None,
- }
- }
-
- pub fn give_home(&mut self, new_home: SchedHome) {
- match self.task_type {
- GreenTask(ref mut home) => {
- *home = Some(new_home);
- }
- SchedTask => {
- rtabort!("type error: used SchedTask as GreenTask");
- }
- }
- }
-
- pub fn take_unwrap_home(&mut self) -> SchedHome {
- match self.task_type {
- GreenTask(ref mut home) => {
- let out = home.take_unwrap();
- return out;
- }
- SchedTask => {
- rtabort!("type error: used SchedTask as GreenTask");
- }
- }
- }
-
- pub fn run(&mut self, f: ||) {
- rtdebug!("run called on task: {}", borrow::to_uint(self));
-
- // The only try/catch block in the world. Attempt to run the task's
- // client-specified code and catch any failures.
- self.unwinder.try(|| {
-
- // Run the task main function, then do some cleanup.
- f.finally(|| {
-
- // First, destroy task-local storage. This may run user dtors.
- //
- // FIXME #8302: Dear diary. I'm so tired and confused.
- // There's some interaction in rustc between the box
- // annihilator and the TLS dtor by which TLS is
- // accessed from annihilated box dtors *after* TLS is
- // destroyed. Somehow setting TLS back to null, as the
- // old runtime did, makes this work, but I don't currently
- // understand how. I would expect that, if the annihilator
- // reinvokes TLS while TLS is uninitialized, that
- // TLS would be reinitialized but never destroyed,
- // but somehow this works. I have no idea what's going
- // on but this seems to make things magically work. FML.
- //
- // (added after initial comment) A possible interaction here is
- // that the destructors for the objects in TLS themselves invoke
- // TLS, or possibly some destructors for those objects being
- // annihilated invoke TLS. Sadly these two operations seemed to
- // be intertwined, and miraculously work for now...
- self.storage.take();
-
- // Destroy remaining boxes. Also may run user dtors.
- unsafe { cleanup::annihilate(); }
-
- // Finally flush and destroy any output handles which the task
- // owns. There are no boxes here, and no user destructors should
- // run after this any more.
- match self.stdout_handle.take() {
- Some(handle) => {
- let mut handle = handle;
- handle.flush();
- }
- None => {}
- }
- self.logger.take();
- })
- });
-
- // Cleanup the dynamic borrowck debugging info
- borrowck::clear_task_borrow_list();
-
- self.death.collect_failure(self.unwinder.to_unwind_result());
- self.destroyed = true;
- }
-
- // New utility functions for homes.
-
- pub fn is_home_no_tls(&self, sched: &~Scheduler) -> bool {
- match self.task_type {
- GreenTask(Some(AnySched)) => { false }
- GreenTask(Some(Sched(SchedHandle { sched_id: ref id, .. }))) => {
- *id == sched.sched_id()
- }
- GreenTask(None) => {
- rtabort!("task without home");
- }
- SchedTask => {
- // Awe yea
- rtabort!("type error: expected: GreenTask, found: SchedTask");
- }
- }
- }
-
- pub fn homed(&self) -> bool {
- match self.task_type {
- GreenTask(Some(AnySched)) => { false }
- GreenTask(Some(Sched(SchedHandle { .. }))) => { true }
- GreenTask(None) => {
- rtabort!("task without home");
- }
- SchedTask => {
- rtabort!("type error: expected: GreenTask, found: SchedTask");
- }
- }
- }
-
- // Grab both the scheduler and the task from TLS and check if the
- // task is executing on an appropriate scheduler.
- pub fn on_appropriate_sched() -> bool {
- Local::borrow(|task: &mut Task| {
- let sched_id = task.sched.get_ref().sched_id();
- let sched_run_anything = task.sched.get_ref().run_anything;
- match task.task_type {
- GreenTask(Some(AnySched)) => {
- rtdebug!("anysched task in sched check ****");
- sched_run_anything
- }
- GreenTask(Some(Sched(SchedHandle { sched_id: ref id, ..}))) => {
- rtdebug!("homed task in sched check ****");
- *id == sched_id
- }
- GreenTask(None) => {
- rtabort!("task without home");
- }
- SchedTask => {
- rtabort!("type error: expected: GreenTask, found: SchedTask");
- }
- }
- })
- }
-}
-
-impl Drop for Task {
- fn drop(&mut self) {
- rtdebug!("called drop for a task: {}", borrow::to_uint(self));
- rtassert!(self.destroyed);
- }
-}
-
-// Coroutines represent nothing more than a context and a stack
-// segment.
-
-impl Coroutine {
-
- pub fn new(stack_pool: &mut StackPool,
- stack_size: Option<uint>,
- start: proc())
- -> Coroutine {
- let stack_size = match stack_size {
- Some(size) => size,
- None => env::min_stack()
- };
- let start = Coroutine::build_start_wrapper(start);
- let mut stack = stack_pool.take_segment(stack_size);
- let initial_context = Context::new(start, &mut stack);
- Coroutine {
- current_stack_segment: stack,
- saved_context: initial_context
- }
- }
-
- pub fn empty() -> Coroutine {
- Coroutine {
- current_stack_segment: StackSegment::new(0),
- saved_context: Context::empty()
- }
- }
-
- fn build_start_wrapper(start: proc()) -> proc() {
- let start_cell = Cell::new(start);
- let wrapper: proc() = proc() {
- // First code after swap to this new context. Run our
- // cleanup job.
- unsafe {
-
- // Again - might work while safe, or it might not.
- Local::borrow(|sched: &mut Scheduler| {
- sched.run_cleanup_job();
- });
-
- // To call the run method on a task we need a direct
- // reference to it. The task is in TLS, so we can
- // simply unsafe_borrow it to get this reference. We
- // need to still have the task in TLS though, so we
- // need to unsafe_borrow.
- let task: *mut Task = Local::unsafe_borrow();
-
- (*task).run(|| {
- // N.B. Removing `start` from the start wrapper
- // closure by emptying a cell is critical for
- // correctness. The ~Task pointer, and in turn the
- // closure used to initialize the first call
- // frame, is destroyed in the scheduler context,
- // not task context. So any captured closures must
- // not contain user-definable dtors that expect to
- // be in task context. By moving `start` out of
- // the closure, all the user code goes our of
- // scope while the task is still running.
- let start = start_cell.take();
- start();
- });
- }
-
- // We remove the sched from the Task in TLS right now.
- let sched: ~Scheduler = Local::take();
- // ... allowing us to give it away when performing a
- // scheduling operation.
- sched.terminate_current_task()
- };
- return wrapper;
- }
-
- /// Destroy coroutine and try to reuse stack segment.
- pub fn recycle(self, stack_pool: &mut StackPool) {
- match self {
- Coroutine { current_stack_segment, .. } => {
- stack_pool.give_segment(current_stack_segment);
- }
- }
- }
-
-}
-
-
-// Just a sanity check to make sure we are catching a Rust-thrown exception
-static UNWIND_TOKEN: uintptr_t = 839147;
-
-impl Unwinder {
- pub fn try(&mut self, f: ||) {
- use unstable::raw::Closure;
-
- unsafe {
- let closure: Closure = transmute(f);
- let code = transmute(closure.code);
- let env = transmute(closure.env);
-
- let token = rust_try(try_fn, code, env);
- assert!(token == 0 || token == UNWIND_TOKEN);
- }
-
- extern fn try_fn(code: *c_void, env: *c_void) {
- unsafe {
- let closure: Closure = Closure {
- code: transmute(code),
- env: transmute(env),
- };
- let closure: || = transmute(closure);
- closure();
- }
- }
-
- extern {
- fn rust_try(f: extern "C" fn(*c_void, *c_void),
- code: *c_void,
- data: *c_void) -> uintptr_t;
- }
- }
-
- pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
- self.unwinding = true;
- self.cause = Some(cause);
- unsafe {
- rust_begin_unwind(UNWIND_TOKEN);
- return transmute(());
- }
- extern {
- fn rust_begin_unwind(token: uintptr_t);
- }
- }
-}
-
-/// This function is invoked from rust's current __morestack function. Segmented
-/// stacks are currently not enabled as segmented stacks, but rather one giant
-/// stack segment. This means that whenever we run out of stack, we want to
-/// truly consider it to be stack overflow rather than allocating a new stack.
-#[no_mangle] // - this is called from C code
-#[no_split_stack] // - it would be sad for this function to trigger __morestack
-#[doc(hidden)] // - Function must be `pub` to get exported, but it's
- // irrelevant for documentation purposes.
-pub extern "C" fn rust_stack_exhausted() {
- use rt::in_green_task_context;
- use rt::task::Task;
- use rt::local::Local;
- use unstable::intrinsics;
-
- unsafe {
- // We're calling this function because the stack just ran out. We need
- // to call some other rust functions, but if we invoke the functions
- // right now it'll just trigger this handler being called again. In
- // order to alleviate this, we move the stack limit to be inside of the
- // red zone that was allocated for exactly this reason.
- let limit = context::get_sp_limit();
- context::record_sp_limit(limit - context::RED_ZONE / 2);
-
- // This probably isn't the best course of action. Ideally one would want
- // to unwind the stack here instead of just aborting the entire process.
- // This is a tricky problem, however. There's a few things which need to
- // be considered:
- //
- // 1. We're here because of a stack overflow, yet unwinding will run
- // destructors and hence arbitrary code. What if that code overflows
- // the stack? One possibility is to use the above allocation of an
- // extra 10k to hope that we don't hit the limit, and if we do then
- // abort the whole program. Not the best, but kind of hard to deal
- // with unless we want to switch stacks.
- //
- // 2. LLVM will optimize functions based on whether they can unwind or
- // not. It will flag functions with 'nounwind' if it believes that
- // the function cannot trigger unwinding, but if we do unwind on
- // stack overflow then it means that we could unwind in any function
- // anywhere. We would have to make sure that LLVM only places the
- // nounwind flag on functions which don't call any other functions.
- //
- // 3. The function that overflowed may have owned arguments. These
- // arguments need to have their destructors run, but we haven't even
- // begun executing the function yet, so unwinding will not run the
- // any landing pads for these functions. If this is ignored, then
- // the arguments will just be leaked.
- //
- // Exactly what to do here is a very delicate topic, and is possibly
- // still up in the air for what exactly to do. Some relevant issues:
- //
- // #3555 - out-of-stack failure leaks arguments
- // #3695 - should there be a stack limit?
- // #9855 - possible strategies which could be taken
- // #9854 - unwinding on windows through __morestack has never worked
- // #2361 - possible implementation of not using landing pads
-
- if in_green_task_context() {
- Local::borrow(|task: &mut Task| {
- let n = task.name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
-
- // See the message below for why this is not emitted to the
- // task's logger. This has the additional conundrum of the
- // logger may not be initialized just yet, meaning that an FFI
- // call would happen to initialized it (calling out to libuv),
- // and the FFI call needs 2MB of stack when we just ran out.
- rterrln!("task '{}' has overflowed its stack", n);
- })
- } else {
- rterrln!("stack overflow in non-task context");
- }
-
- intrinsics::abort();
- }
-}
-
-/// This is the entry point of unwinding for things like lang items and such.
-/// The arguments are normally generated by the compiler, and need to
-/// have static lifetimes.
-pub fn begin_unwind_raw(msg: *c_char, file: *c_char, line: size_t) -> ! {
- use c_str::CString;
- use cast::transmute;
-
- #[inline]
- fn static_char_ptr(p: *c_char) -> &'static str {
- let s = unsafe { CString::new(p, false) };
- match s.as_str() {
- Some(s) => unsafe { transmute::<&str, &'static str>(s) },
- None => rtabort!("message wasn't utf8?")
- }
- }
-
- let msg = static_char_ptr(msg);
- let file = static_char_ptr(file);
-
- begin_unwind(msg, file, line as uint)
-}
-
-/// This is the entry point of unwinding for fail!() and assert!().
-pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
- use any::AnyRefExt;
- use rt::in_green_task_context;
- use rt::local::Local;
- use rt::task::Task;
- use str::Str;
- use unstable::intrinsics;
-
- unsafe {
- let task: *mut Task;
- // Note that this should be the only allocation performed in this block.
- // Currently this means that fail!() on OOM will invoke this code path,
- // but then again we're not really ready for failing on OOM anyway. If
- // we do start doing this, then we should propagate this allocation to
- // be performed in the parent of this task instead of the task that's
- // failing.
- let msg = ~msg as ~Any;
-
- {
- //let msg: &Any = msg;
- let msg_s = match msg.as_ref::<&'static str>() {
- Some(s) => *s,
- None => match msg.as_ref::<~str>() {
- Some(s) => s.as_slice(),
- None => "~Any",
- }
- };
-
- if !in_green_task_context() {
- rterrln!("failed in non-task context at '{}', {}:{}",
- msg_s, file, line);
- intrinsics::abort();
- }
-
- task = Local::unsafe_borrow();
- let n = (*task).name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
-
- // XXX: this should no get forcibly printed to the console, this should
- // either be sent to the parent task (ideally), or get printed to
- // the task's logger. Right now the logger is actually a uvio
- // instance, which uses unkillable blocks internally for various
- // reasons. This will cause serious trouble if the task is failing
- // due to mismanagment of its own kill flag, so calling our own
- // logger in its current state is a bit of a problem.
-
- rterrln!("task '{}' failed at '{}', {}:{}", n, msg_s, file, line);
-
- if (*task).unwinder.unwinding {
- rtabort!("unwinding again");
- }
- }
-
- (*task).unwinder.begin_unwind(msg);
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use rt::test::*;
-
- #[test]
- fn local_heap() {
- do run_in_newsched_task() {
- let a = @5;
- let b = a;
- assert!(*a == 5);
- assert!(*b == 5);
- }
- }
-
- #[test]
- fn tls() {
- use local_data;
- do run_in_newsched_task() {
- local_data_key!(key: @~str)
- local_data::set(key, @~"data");
- assert!(*local_data::get(key, |k| k.map(|k| *k)).unwrap() == ~"data");
- local_data_key!(key2: @~str)
- local_data::set(key2, @~"data");
- assert!(*local_data::get(key2, |k| k.map(|k| *k)).unwrap() == ~"data");
- }
- }
-
- #[test]
- fn unwind() {
- do run_in_newsched_task() {
- let result = spawntask_try(proc()());
- rtdebug!("trying first assert");
- assert!(result.is_ok());
- let result = spawntask_try(proc() fail!());
- rtdebug!("trying second assert");
- assert!(result.is_err());
- }
- }
-
- #[test]
- fn rng() {
- do run_in_uv_task() {
- use rand::{rng, Rng};
- let mut r = rng();
- let _ = r.next_u32();
- }
- }
-
- #[test]
- fn logging() {
- do run_in_uv_task() {
- info!("here i am. logging in a newsched task");
- }
- }
-
- #[test]
- fn comm_oneshot() {
- use comm::*;
-
- do run_in_newsched_task {
- let (port, chan) = oneshot();
- chan.send(10);
- assert!(port.recv() == 10);
- }
- }
-
- #[test]
- fn comm_stream() {
- use comm::*;
-
- do run_in_newsched_task() {
- let (port, chan) = stream();
- chan.send(10);
- assert!(port.recv() == 10);
- }
- }
-
- #[test]
- fn comm_shared_chan() {
- use comm::*;
-
- do run_in_newsched_task() {
- let (port, chan) = stream();
- let chan = SharedChan::new(chan);
- chan.send(10);
- assert!(port.recv() == 10);
- }
- }
-
- #[test]
- fn heap_cycles() {
- use option::{Option, Some, None};
-
- do run_in_newsched_task {
- struct List {
- next: Option<@mut List>,
- }
-
- let a = @mut List { next: None };
- let b = @mut List { next: Some(a) };
-
- a.next = Some(b);
- }
- }
-
- #[test]
- #[should_fail]
- fn test_begin_unwind() { begin_unwind("cause", file!(), line!()) }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
-
-use cell::Cell;
-use clone::Clone;
-use container::Container;
-use iter::{Iterator, range};
-use option::{Some, None};
-use os;
-use path::GenericPath;
-use path::Path;
-use rand::Rng;
-use rand;
-use result::{Result, Ok, Err};
-use rt::basic;
-use rt::comm::oneshot;
-use rt::new_event_loop;
-use rt::sched::Scheduler;
-use rt::sleeper_list::SleeperList;
-use rt::task::Task;
-use rt::task::UnwindResult;
-use rt::thread::Thread;
-use rt::work_queue::WorkQueue;
-use unstable::{run_in_bare_thread};
-use vec::{OwnedVector, MutableVector, ImmutableVector};
-
-pub fn new_test_uv_sched() -> Scheduler {
-
- let queue = WorkQueue::new();
- let queues = ~[queue.clone()];
-
- let mut sched = Scheduler::new(new_event_loop(),
- queue,
- queues,
- SleeperList::new());
-
- // Don't wait for the Shutdown message
- sched.no_sleep = true;
- return sched;
-
-}
-
-pub fn new_test_sched() -> Scheduler {
-
- let queue = WorkQueue::new();
- let queues = ~[queue.clone()];
-
- let mut sched = Scheduler::new(basic::event_loop(),
- queue,
- queues,
- SleeperList::new());
-
- // Don't wait for the Shutdown message
- sched.no_sleep = true;
- return sched;
-}
-
-pub fn run_in_uv_task(f: proc()) {
- let f = Cell::new(f);
- do run_in_bare_thread {
- run_in_uv_task_core(f.take());
- }
-}
-
-pub fn run_in_newsched_task(f: proc()) {
- let f = Cell::new(f);
- do run_in_bare_thread {
- run_in_newsched_task_core(f.take());
- }
-}
-
-pub fn run_in_uv_task_core(f: proc()) {
-
- use rt::sched::Shutdown;
-
- let mut sched = ~new_test_uv_sched();
- let exit_handle = sched.make_handle();
-
- let on_exit: proc(UnwindResult) = proc(exit_status: UnwindResult) {
- let mut exit_handle = exit_handle;
- exit_handle.send(Shutdown);
- rtassert!(exit_status.is_success());
- };
- let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
- task.death.on_exit = Some(on_exit);
-
- sched.bootstrap(task);
-}
-
-pub fn run_in_newsched_task_core(f: proc()) {
- use rt::sched::Shutdown;
-
- let mut sched = ~new_test_sched();
- let exit_handle = sched.make_handle();
-
- let on_exit: proc(UnwindResult) = proc(exit_status: UnwindResult) {
- let mut exit_handle = exit_handle;
- exit_handle.send(Shutdown);
- rtassert!(exit_status.is_success());
- };
- let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
- task.death.on_exit = Some(on_exit);
-
- sched.bootstrap(task);
-}
-
-#[cfg(target_os="macos")]
-#[allow(non_camel_case_types)]
-mod darwin_fd_limit {
- /*!
- * darwin_fd_limit exists to work around an issue where launchctl on Mac OS X defaults the
- * rlimit maxfiles to 256/unlimited. The default soft limit of 256 ends up being far too low
- * for our multithreaded scheduler testing, depending on the number of cores available.
- *
- * This fixes issue #7772.
- */
-
- use libc;
- type rlim_t = libc::uint64_t;
- struct rlimit {
- rlim_cur: rlim_t,
- rlim_max: rlim_t
- }
- #[nolink]
- extern {
- // name probably doesn't need to be mut, but the C function doesn't specify const
- fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
- oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
- newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
- fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
- fn setrlimit(resource: libc::c_int, rlp: *rlimit) -> libc::c_int;
- }
- static CTL_KERN: libc::c_int = 1;
- static KERN_MAXFILESPERPROC: libc::c_int = 29;
- static RLIMIT_NOFILE: libc::c_int = 8;
-
- pub unsafe fn raise_fd_limit() {
- // The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
- // sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
- use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
- use mem::size_of_val;
- use os::last_os_error;
-
- // Fetch the kern.maxfilesperproc value
- let mut mib: [libc::c_int, ..2] = [CTL_KERN, KERN_MAXFILESPERPROC];
- let mut maxfiles: libc::c_int = 0;
- let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
- if sysctl(to_mut_unsafe_ptr(&mut mib[0]), 2,
- to_mut_unsafe_ptr(&mut maxfiles) as *mut libc::c_void,
- to_mut_unsafe_ptr(&mut size),
- mut_null(), 0) != 0 {
- let err = last_os_error();
- error!("raise_fd_limit: error calling sysctl: {}", err);
- return;
- }
-
- // Fetch the current resource limits
- let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
- if getrlimit(RLIMIT_NOFILE, to_mut_unsafe_ptr(&mut rlim)) != 0 {
- let err = last_os_error();
- error!("raise_fd_limit: error calling getrlimit: {}", err);
- return;
- }
-
- // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
- rlim.rlim_cur = ::cmp::min(maxfiles as rlim_t, rlim.rlim_max);
-
- // Set our newly-increased resource limit
- if setrlimit(RLIMIT_NOFILE, to_unsafe_ptr(&rlim)) != 0 {
- let err = last_os_error();
- error!("raise_fd_limit: error calling setrlimit: {}", err);
- return;
- }
- }
-}
-
-#[cfg(not(target_os="macos"))]
-mod darwin_fd_limit {
- pub unsafe fn raise_fd_limit() {}
-}
-
-#[doc(hidden)]
-pub fn prepare_for_lots_of_tests() {
- // Bump the fd limit on OS X. See darwin_fd_limit for an explanation.
- unsafe { darwin_fd_limit::raise_fd_limit() }
-}
-
-/// Create more than one scheduler and run a function in a task
-/// in one of the schedulers. The schedulers will stay alive
-/// until the function `f` returns.
-pub fn run_in_mt_newsched_task(f: proc()) {
- use os;
- use from_str::FromStr;
- use rt::sched::Shutdown;
- use rt::util;
-
- // see comment in other function (raising fd limits)
- prepare_for_lots_of_tests();
-
- let f = Cell::new(f);
-
- do run_in_bare_thread {
- let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
- Some(nstr) => FromStr::from_str(nstr).unwrap(),
- None => {
- if util::limit_thread_creation_due_to_osx_and_valgrind() {
- 1
- } else {
- // Using more threads than cores in test code
- // to force the OS to preempt them frequently.
- // Assuming that this help stress test concurrent types.
- util::num_cpus() * 2
- }
- }
- };
-
- let sleepers = SleeperList::new();
-
- let mut handles = ~[];
- let mut scheds = ~[];
- let mut work_queues = ~[];
-
- for _ in range(0u, nthreads) {
- let work_queue = WorkQueue::new();
- work_queues.push(work_queue);
- }
-
- for i in range(0u, nthreads) {
- let loop_ = new_event_loop();
- let mut sched = ~Scheduler::new(loop_,
- work_queues[i].clone(),
- work_queues.clone(),
- sleepers.clone());
- let handle = sched.make_handle();
-
- handles.push(handle);
- scheds.push(sched);
- }
-
- let handles = handles; // Work around not being able to capture mut
- let on_exit: proc(UnwindResult) = proc(exit_status: UnwindResult) {
- // Tell schedulers to exit
- let mut handles = handles;
- for handle in handles.mut_iter() {
- handle.send(Shutdown);
- }
-
- rtassert!(exit_status.is_success());
- };
- let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, f.take());
- main_task.death.on_exit = Some(on_exit);
-
- let mut threads = ~[];
- let main_task = Cell::new(main_task);
-
- let main_thread = {
- let sched = scheds.pop();
- let sched_cell = Cell::new(sched);
- do Thread::start {
- let sched = sched_cell.take();
- sched.bootstrap(main_task.take());
- }
- };
- threads.push(main_thread);
-
- while !scheds.is_empty() {
- let mut sched = scheds.pop();
- let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
- rtdebug!("bootstrapping non-primary scheduler");
- };
- let bootstrap_task_cell = Cell::new(bootstrap_task);
- let sched_cell = Cell::new(sched);
- let thread = do Thread::start {
- let sched = sched_cell.take();
- sched.bootstrap(bootstrap_task_cell.take());
- };
-
- threads.push(thread);
- }
-
- // Wait for schedulers
- for thread in threads.move_iter() {
- thread.join();
- }
- }
-
-}
-
-/// Test tasks will abort on failure instead of unwinding
-pub fn spawntask(f: proc()) {
- Scheduler::run_task(Task::build_child(None, f));
-}
-
-/// Create a new task and run it right now. Aborts on failure
-pub fn spawntask_later(f: proc()) {
- Scheduler::run_task_later(Task::build_child(None, f));
-}
-
-pub fn spawntask_random(f: proc()) {
- use rand::{Rand, rng};
-
- let mut rng = rng();
- let run_now: bool = Rand::rand(&mut rng);
-
- if run_now {
- spawntask(f)
- } else {
- spawntask_later(f)
- }
-}
-
-pub fn spawntask_try(f: proc()) -> Result<(),()> {
-
- let (port, chan) = oneshot();
- let on_exit: proc(UnwindResult) = proc(exit_status) {
- chan.send(exit_status)
- };
-
- let mut new_task = Task::build_root(None, f);
- new_task.death.on_exit = Some(on_exit);
-
- Scheduler::run_task(new_task);
-
- let exit_status = port.recv();
- if exit_status.is_success() { Ok(()) } else { Err(()) }
-
-}
-
-/// Spawn a new task in a new scheduler and return a thread handle.
-pub fn spawntask_thread(f: proc()) -> Thread<()> {
-
- let f = Cell::new(f);
-
- let thread = do Thread::start {
- run_in_newsched_task_core(f.take());
- };
-
- return thread;
-}
-
-/// Get a ~Task for testing purposes other than actually scheduling it.
-pub fn with_test_task(blk: proc(~Task) -> ~Task) {
- do run_in_bare_thread {
- let mut sched = ~new_test_sched();
- let task = blk(~Task::new_root(&mut sched.stack_pool,
- None,
- proc() {}));
- cleanup_task(task);
- }
-}
-
-/// Use to cleanup tasks created for testing but not "run".
-pub fn cleanup_task(mut task: ~Task) {
- task.destroyed = true;
-}
-
-/// Get a port number, starting at 9600, for use in tests
-pub fn next_test_port() -> u16 {
- use unstable::mutex::{Mutex, MUTEX_INIT};
- static mut lock: Mutex = MUTEX_INIT;
- static mut next_offset: u16 = 0;
- unsafe {
- let base = base_port();
- lock.lock();
- let ret = base + next_offset;
- next_offset += 1;
- lock.unlock();
- return ret;
- }
-}
-
-/// Get a temporary path which could be the location of a unix socket
-pub fn next_test_unix() -> Path {
- if cfg!(unix) {
- os::tmpdir().join(rand::task_rng().gen_ascii_str(20))
- } else {
- Path::new(r"\\.\pipe\" + rand::task_rng().gen_ascii_str(20))
- }
-}
-
-/// Get a unique IPv4 localhost:port pair starting at 9600
-pub fn next_test_ip4() -> SocketAddr {
- SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: next_test_port() }
-}
-
-/// Get a unique IPv6 localhost:port pair starting at 9600
-pub fn next_test_ip6() -> SocketAddr {
- SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1), port: next_test_port() }
-}
-
-/*
-XXX: Welcome to MegaHack City.
-
-The bots run multiple builds at the same time, and these builds
-all want to use ports. This function figures out which workspace
-it is running in and assigns a port range based on it.
-*/
-fn base_port() -> u16 {
- use os;
- use str::StrSlice;
- use vec::ImmutableVector;
-
- let base = 9600u16;
- let range = 1000u16;
-
- let bases = [
- ("32-opt", base + range * 1),
- ("32-noopt", base + range * 2),
- ("64-opt", base + range * 3),
- ("64-noopt", base + range * 4),
- ("64-opt-vg", base + range * 5),
- ("all-opt", base + range * 6),
- ("snap3", base + range * 7),
- ("dist", base + range * 8)
- ];
-
- // FIXME (#9639): This needs to handle non-utf8 paths
- let path = os::getcwd();
- let path_s = path.as_str().unwrap();
-
- let mut final_base = base;
-
- for &(dir, base) in bases.iter() {
- if path_s.contains(dir) {
- final_base = base;
- break;
- }
- }
-
- return final_base;
-}
-
-/// Get a constant that represents the number of times to repeat
-/// stress tests. Default 1.
-pub fn stress_factor() -> uint {
- use os::getenv;
- use from_str::from_str;
-
- match getenv("RUST_RT_STRESS") {
- Some(val) => from_str::<uint>(val).unwrap(),
- None => 1
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Native os-thread management
-//!
-//! This modules contains bindings necessary for managing OS-level threads.
-//! These functions operate outside of the rust runtime, creating threads
-//! which are not used for scheduling in any way.
-
-#[allow(non_camel_case_types)];
-
-use cast;
-use kinds::Send;
-use libc;
-use ops::Drop;
-use option::{Option, Some, None};
-use ptr;
-use uint;
-
-#[cfg(windows)]
-use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T,
- LPVOID, DWORD, LPDWORD, HANDLE};
-
-#[cfg(windows)] type rust_thread = HANDLE;
-#[cfg(unix)] type rust_thread = libc::pthread_t;
-#[cfg(windows)] type rust_thread_return = DWORD;
-#[cfg(unix)] type rust_thread_return = *libc::c_void;
-
-type StartFn = extern "C" fn(*libc::c_void) -> rust_thread_return;
-
-/// This struct represents a native thread's state. This is used to join on an
-/// existing thread created in the join-able state.
-pub struct Thread<T> {
- priv native: rust_thread,
- priv joined: bool,
- priv packet: ~Option<T>,
-}
-
-static DEFAULT_STACK_SIZE: libc::size_t = 1024*1024;
-
-// This is the starting point of rust os threads. The first thing we do
-// is make sure that we don't trigger __morestack (also why this has a
-// no_split_stack annotation), and then we extract the main function
-// and invoke it.
-#[no_split_stack]
-extern fn thread_start(main: *libc::c_void) -> rust_thread_return {
- use rt::context;
- unsafe {
- context::record_stack_bounds(0, uint::max_value);
- let f: ~proc() = cast::transmute(main);
- (*f)();
- cast::transmute(0 as rust_thread_return)
- }
-}
-
-// There are two impl blocks b/c if T were specified at the top then it's just a
-// pain to specify a type parameter on Thread::spawn (which doesn't need the
-// type parameter).
-impl Thread<()> {
-
- /// Starts execution of a new OS thread.
- ///
- /// This function will not wait for the thread to join, but a handle to the
- /// thread will be returned.
- ///
- /// Note that the handle returned is used to acquire the return value of the
- /// procedure `main`. The `join` function will wait for the thread to finish
- /// and return the value that `main` generated.
- ///
- /// Also note that the `Thread` returned will *always* wait for the thread
- /// to finish executing. This means that even if `join` is not explicitly
- /// called, when the `Thread` falls out of scope its destructor will block
- /// waiting for the OS thread.
- pub fn start<T: Send>(main: proc() -> T) -> Thread<T> {
-
- // We need the address of the packet to fill in to be stable so when
- // `main` fills it in it's still valid, so allocate an extra ~ box to do
- // so.
- let packet = ~None;
- let packet2: *mut Option<T> = unsafe {
- *cast::transmute::<&~Option<T>, **mut Option<T>>(&packet)
- };
- let main: proc() = proc() unsafe { *packet2 = Some(main()); };
- let native = unsafe { native_thread_create(~main) };
-
- Thread {
- native: native,
- joined: false,
- packet: packet,
- }
- }
-
- /// This will spawn a new thread, but it will not wait for the thread to
- /// finish, nor is it possible to wait for the thread to finish.
- ///
- /// This corresponds to creating threads in the 'detached' state on unix
- /// systems. Note that platforms may not keep the main program alive even if
- /// there are detached thread still running around.
- pub fn spawn(main: proc()) {
- unsafe {
- let handle = native_thread_create(~main);
- native_thread_detach(handle);
- }
- }
-}
-
-impl<T: Send> Thread<T> {
- /// Wait for this thread to finish, returning the result of the thread's
- /// calculation.
- pub fn join(mut self) -> T {
- assert!(!self.joined);
- unsafe { native_thread_join(self.native) };
- self.joined = true;
- assert!(self.packet.is_some());
- self.packet.take_unwrap()
- }
-}
-
-#[unsafe_destructor]
-impl<T: Send> Drop for Thread<T> {
- fn drop(&mut self) {
- // This is required for correctness. If this is not done then the thread
- // would fill in a return box which no longer exists.
- if !self.joined {
- unsafe { native_thread_join(self.native) };
- }
- }
-}
-
-#[cfg(windows)]
-unsafe fn native_thread_create(p: ~proc()) -> rust_thread {
- let arg: *mut libc::c_void = cast::transmute(p);
- CreateThread(ptr::mut_null(), DEFAULT_STACK_SIZE, thread_start,
- arg, 0, ptr::mut_null())
-}
-
-#[cfg(windows)]
-unsafe fn native_thread_join(native: rust_thread) {
- use libc::consts::os::extra::INFINITE;
- WaitForSingleObject(native, INFINITE);
-}
-
-#[cfg(windows)]
-unsafe fn native_thread_detach(native: rust_thread) {
- assert!(libc::CloseHandle(native) != 0);
-}
-
-#[cfg(unix)]
-unsafe fn native_thread_create(p: ~proc()) -> rust_thread {
- use unstable::intrinsics;
- use libc::consts::os::posix01::PTHREAD_CREATE_JOINABLE;
-
- let mut native: libc::pthread_t = intrinsics::uninit();
- let mut attr: libc::pthread_attr_t = intrinsics::uninit();
- assert_eq!(pthread_attr_init(&mut attr), 0);
- assert_eq!(pthread_attr_setstacksize(&mut attr, DEFAULT_STACK_SIZE), 0);
- assert_eq!(pthread_attr_setdetachstate(&mut attr, PTHREAD_CREATE_JOINABLE), 0);
-
- let arg: *libc::c_void = cast::transmute(p);
- assert_eq!(pthread_create(&mut native, &attr, thread_start, arg), 0);
- native
-}
-
-#[cfg(unix)]
-unsafe fn native_thread_join(native: rust_thread) {
- assert_eq!(pthread_join(native, ptr::null()), 0);
-}
-
-#[cfg(unix)]
-fn native_thread_detach(native: rust_thread) {
- unsafe { assert_eq!(pthread_detach(native), 0) }
-}
-
-#[cfg(windows)]
-extern "system" {
- fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
- dwStackSize: SIZE_T,
- lpStartAddress: StartFn,
- lpParameter: LPVOID,
- dwCreationFlags: DWORD,
- lpThreadId: LPDWORD) -> HANDLE;
- fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
-}
-
-#[cfg(unix)]
-extern {
- fn pthread_create(native: *mut libc::pthread_t,
- attr: *libc::pthread_attr_t,
- f: StartFn,
- value: *libc::c_void) -> libc::c_int;
- fn pthread_join(native: libc::pthread_t,
- value: **libc::c_void) -> libc::c_int;
- fn pthread_attr_init(attr: *mut libc::pthread_attr_t) -> libc::c_int;
- fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
- stack_size: libc::size_t) -> libc::c_int;
- fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
- state: libc::c_int) -> libc::c_int;
- fn pthread_detach(thread: libc::pthread_t) -> libc::c_int;
-}
-
-#[cfg(test)]
-mod tests {
- use super::Thread;
-
- #[test]
- fn smoke() { do Thread::start {}.join(); }
-
- #[test]
- fn data() { assert_eq!(do Thread::start { 1 }.join(), 1); }
-
- #[test]
- fn detached() { do Thread::spawn {} }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use libc::c_void;
-#[cfg(unix)]
-use libc::c_int;
-#[cfg(unix)]
-use ptr::null;
-#[cfg(windows)]
-use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
-
-#[cfg(unix)]
-pub type Key = pthread_key_t;
-
-#[cfg(unix)]
-pub unsafe fn create(key: &mut Key) {
- assert_eq!(0, pthread_key_create(key, null()));
-}
-
-#[cfg(unix)]
-pub unsafe fn set(key: Key, value: *mut c_void) {
- assert_eq!(0, pthread_setspecific(key, value));
-}
-
-#[cfg(unix)]
-pub unsafe fn get(key: Key) -> *mut c_void {
- pthread_getspecific(key)
-}
-
-#[cfg(unix)]
-pub unsafe fn destroy(key: Key) {
- assert_eq!(0, pthread_key_delete(key));
-}
-
-#[cfg(target_os="macos")]
-#[allow(non_camel_case_types)] // foreign type
-type pthread_key_t = ::libc::c_ulong;
-
-#[cfg(target_os="linux")]
-#[cfg(target_os="freebsd")]
-#[cfg(target_os="android")]
-#[allow(non_camel_case_types)] // foreign type
-type pthread_key_t = ::libc::c_uint;
-
-#[cfg(unix)]
-extern {
- fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int;
- fn pthread_key_delete(key: pthread_key_t) -> c_int;
- fn pthread_getspecific(key: pthread_key_t) -> *mut c_void;
- fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int;
-}
-
-#[cfg(windows)]
-pub type Key = DWORD;
-
-#[cfg(windows)]
-pub unsafe fn create(key: &mut Key) {
- static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
- *key = TlsAlloc();
- assert!(*key != TLS_OUT_OF_INDEXES);
-}
-
-#[cfg(windows)]
-pub unsafe fn set(key: Key, value: *mut c_void) {
- assert!(0 != TlsSetValue(key, value))
-}
-
-#[cfg(windows)]
-pub unsafe fn get(key: Key) -> *mut c_void {
- TlsGetValue(key)
-}
-
-#[cfg(windows)]
-pub unsafe fn destroy(key: Key) {
- assert!(TlsFree(key) != 0);
-}
-
-#[cfg(windows)]
-extern "system" {
- fn TlsAlloc() -> DWORD;
- fn TlsFree(dwTlsIndex: DWORD) -> BOOL;
- fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
- fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
-}
-
-#[test]
-fn tls_smoke_test() {
- use cast::transmute;
- unsafe {
- let mut key = 0;
- let value = ~20;
- create(&mut key);
- set(key, transmute(value));
- let value: ~int = transmute(get(key));
- assert_eq!(value, ~20);
- let value = ~30;
- set(key, transmute(value));
- let value: ~int = transmute(get(key));
- assert_eq!(value, ~30);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A very simple unsynchronized channel type for sending buffered data from
-//! scheduler context to task context.
-//!
-//! XXX: This would be safer to use if split into two types like Port/Chan
-
-use option::*;
-use clone::Clone;
-use super::rc::RC;
-use rt::sched::Scheduler;
-use rt::kill::BlockedTask;
-use rt::local::Local;
-use vec::OwnedVector;
-use container::Container;
-
-struct TubeState<T> {
- blocked_task: Option<BlockedTask>,
- buf: ~[T]
-}
-
-pub struct Tube<T> {
- priv p: RC<TubeState<T>>
-}
-
-impl<T> Tube<T> {
- pub fn new() -> Tube<T> {
- Tube {
- p: RC::new(TubeState {
- blocked_task: None,
- buf: ~[]
- })
- }
- }
-
- pub fn send(&mut self, val: T) {
- rtdebug!("tube send");
- unsafe {
- let state = self.p.unsafe_borrow_mut();
- (*state).buf.push(val);
-
- if (*state).blocked_task.is_some() {
- // There's a waiting task. Wake it up
- rtdebug!("waking blocked tube");
- let task = (*state).blocked_task.take_unwrap();
- let sched: ~Scheduler = Local::take();
- sched.resume_blocked_task_immediately(task);
- }
- }
- }
-
- pub fn recv(&mut self) -> T {
- unsafe {
- let state = self.p.unsafe_borrow_mut();
- if !(*state).buf.is_empty() {
- return (*state).buf.shift();
- } else {
- // Block and wait for the next message
- rtdebug!("blocking on tube recv");
- assert!(self.p.refcount() > 1); // There better be somebody to wake us up
- assert!((*state).blocked_task.is_none());
- let sched: ~Scheduler = Local::take();
- sched.deschedule_running_task_and_then(|_, task| {
- (*state).blocked_task = Some(task);
- });
- rtdebug!("waking after tube recv");
- let buf = &mut (*state).buf;
- assert!(!buf.is_empty());
- return buf.shift();
- }
- }
- }
-}
-
-impl<T> Clone for Tube<T> {
- fn clone(&self) -> Tube<T> {
- Tube { p: self.p.clone() }
- }
-}
-
-#[cfg(test)]
-mod test {
- use cell::Cell;
- use rt::test::*;
- use rt::rtio::EventLoop;
- use rt::sched::Scheduler;
- use rt::local::Local;
- use super::*;
- use prelude::*;
-
- #[test]
- fn simple_test() {
- do run_in_newsched_task {
- let mut tube: Tube<int> = Tube::new();
- let tube_clone = tube.clone();
- let tube_clone_cell = Cell::new(tube_clone);
- let sched: ~Scheduler = Local::take();
- sched.deschedule_running_task_and_then(|sched, task| {
- let mut tube_clone = tube_clone_cell.take();
- tube_clone.send(1);
- sched.enqueue_blocked_task(task);
- });
-
- assert!(tube.recv() == 1);
- }
- }
-
- #[test]
- fn blocking_test() {
- do run_in_newsched_task {
- let mut tube: Tube<int> = Tube::new();
- let tube_clone = tube.clone();
- let tube_clone = Cell::new(tube_clone);
- let sched: ~Scheduler = Local::take();
- sched.deschedule_running_task_and_then(|sched, task| {
- let tube_clone = Cell::new(tube_clone.take());
- do sched.event_loop.callback {
- let mut tube_clone = tube_clone.take();
- // The task should be blocked on this now and
- // sending will wake it up.
- tube_clone.send(1);
- }
- sched.enqueue_blocked_task(task);
- });
-
- assert!(tube.recv() == 1);
- }
- }
-
- #[test]
- fn many_blocking_test() {
- static MAX: int = 100;
-
- do run_in_newsched_task {
- let mut tube: Tube<int> = Tube::new();
- let tube_clone = tube.clone();
- let tube_clone = Cell::new(tube_clone);
- let sched: ~Scheduler = Local::take();
- sched.deschedule_running_task_and_then(|sched, task| {
- callback_send(tube_clone.take(), 0);
-
- fn callback_send(tube: Tube<int>, i: int) {
- if i == 100 { return; }
-
- let tube = Cell::new(Cell::new(tube));
- Local::borrow(|sched: &mut Scheduler| {
- let tube = tube.take();
- do sched.event_loop.callback {
- let mut tube = tube.take();
- // The task should be blocked on this now and
- // sending will wake it up.
- tube.send(i);
- callback_send(tube, i + 1);
- }
- })
- }
-
- sched.enqueue_blocked_task(task);
- });
-
- for i in range(0, MAX) {
- let j = tube.recv();
- assert!(j == i);
- }
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::Container;
-use fmt;
-use from_str::FromStr;
-use libc;
-use option::{Some, None, Option};
-use os;
-use str::StrSlice;
-use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
-use unstable::running_on_valgrind;
-
-// Indicates whether we should perform expensive sanity checks, including rtassert!
-// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
-pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);
-
-/// Get the number of cores available
-pub fn num_cpus() -> uint {
- unsafe {
- return rust_get_num_cpus();
- }
-
- extern {
- fn rust_get_num_cpus() -> libc::uintptr_t;
- }
-}
-
-/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
-/// wired into it; this is a hard limit and requires rebuilding valgrind if you
-/// want to go beyond it. Normally this is not a problem, but in some tests, we
-/// produce a lot of threads casually. Making lots of threads alone might not
-/// be a problem _either_, except on OSX, the segments produced for new threads
-/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
-/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
-/// perfect storm of creating "too many mappings" for valgrind to handle when
-/// running certain stress tests in the runtime.
-pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
- (cfg!(target_os="macos")) && running_on_valgrind()
-}
-
-/// Get's the number of scheduler threads requested by the environment
-/// either `RUST_THREADS` or `num_cpus`.
-pub fn default_sched_threads() -> uint {
- match os::getenv("RUST_THREADS") {
- Some(nstr) => {
- let opt_n: Option<uint> = FromStr::from_str(nstr);
- match opt_n {
- Some(n) if n > 0 => n,
- _ => rtabort!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
- }
- }
- None => {
- if limit_thread_creation_due_to_osx_and_valgrind() {
- 1
- } else {
- num_cpus()
- }
- }
- }
-}
-
-pub fn dumb_println(args: &fmt::Arguments) {
- use io::native::file::FileDesc;
- use io;
- use libc;
- let mut out = FileDesc::new(libc::STDERR_FILENO, false);
- fmt::writeln(&mut out as &mut io::Writer, args);
-}
-
-pub fn abort(msg: &str) -> ! {
- let msg = if !msg.is_empty() { msg } else { "aborted" };
- let hash = msg.chars().fold(0, |accum, val| accum + (val as uint) );
- let quote = match hash % 10 {
- 0 => "
-It was from the artists and poets that the pertinent answers came, and I
-know that panic would have broken loose had they been able to compare notes.
-As it was, lacking their original letters, I half suspected the compiler of
-having asked leading questions, or of having edited the correspondence in
-corroboration of what he had latently resolved to see.",
- 1 => "
-There are not many persons who know what wonders are opened to them in the
-stories and visions of their youth; for when as children we listen and dream,
-we think but half-formed thoughts, and when as men we try to remember, we are
-dulled and prosaic with the poison of life. But some of us awake in the night
-with strange phantasms of enchanted hills and gardens, of fountains that sing
-in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
-down to sleeping cities of bronze and stone, and of shadowy companies of heroes
-that ride caparisoned white horses along the edges of thick forests; and then
-we know that we have looked back through the ivory gates into that world of
-wonder which was ours before we were wise and unhappy.",
- 2 => "
-Instead of the poems I had hoped for, there came only a shuddering blackness
-and ineffable loneliness; and I saw at last a fearful truth which no one had
-ever dared to breathe before — the unwhisperable secret of secrets — The fact
-that this city of stone and stridor is not a sentient perpetuation of Old New
-York as London is of Old London and Paris of Old Paris, but that it is in fact
-quite dead, its sprawling body imperfectly embalmed and infested with queer
-animate things which have nothing to do with it as it was in life.",
- 3 => "
-The ocean ate the last of the land and poured into the smoking gulf, thereby
-giving up all it had ever conquered. From the new-flooded lands it flowed
-again, uncovering death and decay; and from its ancient and immemorial bed it
-trickled loathsomely, uncovering nighted secrets of the years when Time was
-young and the gods unborn. Above the waves rose weedy remembered spires. The
-moon laid pale lilies of light on dead London, and Paris stood up from its damp
-grave to be sanctified with star-dust. Then rose spires and monoliths that were
-weedy but not remembered; terrible spires and monoliths of lands that men never
-knew were lands...",
- 4 => "
-There was a night when winds from unknown spaces whirled us irresistibly into
-limitless vacuum beyond all thought and entity. Perceptions of the most
-maddeningly untransmissible sort thronged upon us; perceptions of infinity
-which at the time convulsed us with joy, yet which are now partly lost to my
-memory and partly incapable of presentation to others.",
- _ => "You've met with a terrible fate, haven't you?"
- };
- rterrln!("{}", "");
- rterrln!("{}", quote);
- rterrln!("{}", "");
- rterrln!("fatal runtime error: {}", msg);
-
- abort();
-
- fn abort() -> ! {
- unsafe { libc::abort() }
- }
-}
-
-static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;
-
-pub fn set_exit_status(code: int) {
- unsafe { EXIT_STATUS.store(code, SeqCst) }
-}
-
-pub fn get_exit_status() -> int {
- unsafe { EXIT_STATUS.load(SeqCst) }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::Container;
-use option::*;
-use vec::OwnedVector;
-use unstable::sync::Exclusive;
-use cell::Cell;
-use kinds::Send;
-use clone::Clone;
-
-pub struct WorkQueue<T> {
- // XXX: Another mystery bug fixed by boxing this lock
- priv queue: ~Exclusive<~[T]>
-}
-
-impl<T: Send> WorkQueue<T> {
- pub fn new() -> WorkQueue<T> {
- WorkQueue {
- queue: ~Exclusive::new(~[])
- }
- }
-
- pub fn push(&mut self, value: T) {
- unsafe {
- let value = Cell::new(value);
- self.queue.with(|q| q.unshift(value.take()) );
- }
- }
-
- pub fn pop(&mut self) -> Option<T> {
- unsafe {
- self.queue.with(|q| {
- if !q.is_empty() {
- Some(q.shift())
- } else {
- None
- }
- })
- }
- }
-
- pub fn steal(&mut self) -> Option<T> {
- unsafe {
- self.queue.with(|q| {
- if !q.is_empty() {
- Some(q.pop())
- } else {
- None
- }
- })
- }
- }
-
- pub fn is_empty(&self) -> bool {
- unsafe {
- self.queue.with_imm(|q| q.is_empty() )
- }
- }
-}
-
-impl<T> Clone for WorkQueue<T> {
- fn clone(&self) -> WorkQueue<T> {
- WorkQueue {
- queue: self.queue.clone()
- }
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Process spawning.
-
-#[allow(missing_doc)];
-
-use cell::Cell;
-use comm::{stream, SharedChan};
-use io::Reader;
-use io::process::ProcessExit;
-use io::process;
-use io;
-use libc::{pid_t, c_int};
-use libc;
-use prelude::*;
-
-/**
- * A value representing a child process.
- *
- * The lifetime of this value is linked to the lifetime of the actual
- * process - the Process destructor calls self.finish() which waits
- * for the process to terminate.
- */
-pub struct Process {
- priv inner: process::Process,
-}
-
-/// Options that can be given when starting a Process.
-pub struct ProcessOptions<'self> {
- /**
- * If this is None then the new process will have the same initial
- * environment as the parent process.
- *
- * If this is Some(vec-of-names-and-values) then the new process will
- * have an environment containing the given named values only.
- */
- env: Option<~[(~str, ~str)]>,
-
- /**
- * If this is None then the new process will use the same initial working
- * directory as the parent process.
- *
- * If this is Some(path) then the new process will use the given path
- * for its initial working directory.
- */
- dir: Option<&'self Path>,
-
- /**
- * If this is None then a new pipe will be created for the new process's
- * input and Process.input() will provide a Writer to write to this pipe.
- *
- * If this is Some(file-descriptor) then the new process will read its input
- * from the given file descriptor, Process.input_redirected() will return
- * true, and Process.input() will fail.
- */
- in_fd: Option<c_int>,
-
- /**
- * If this is None then a new pipe will be created for the new program's
- * output and Process.output() will provide a Reader to read from this pipe.
- *
- * If this is Some(file-descriptor) then the new process will write its output
- * to the given file descriptor, Process.output_redirected() will return
- * true, and Process.output() will fail.
- */
- out_fd: Option<c_int>,
-
- /**
- * If this is None then a new pipe will be created for the new program's
- * error stream and Process.error() will provide a Reader to read from this pipe.
- *
- * If this is Some(file-descriptor) then the new process will write its error output
- * to the given file descriptor, Process.error_redirected() will return true, and
- * and Process.error() will fail.
- */
- err_fd: Option<c_int>,
-}
-
-impl <'self> ProcessOptions<'self> {
- /// Return a ProcessOptions that has None in every field.
- pub fn new<'a>() -> ProcessOptions<'a> {
- ProcessOptions {
- env: None,
- dir: None,
- in_fd: None,
- out_fd: None,
- err_fd: None,
- }
- }
-}
-
-/// The output of a finished process.
-pub struct ProcessOutput {
- /// The status (exit code) of the process.
- status: ProcessExit,
-
- /// The data that the process wrote to stdout.
- output: ~[u8],
-
- /// The data that the process wrote to stderr.
- error: ~[u8],
-}
-
-impl Process {
- /**
- * Spawns a new Process.
- *
- * # Arguments
- *
- * * prog - The path to an executable.
- * * args - Vector of arguments to pass to the child process.
- * * options - Options to configure the environment of the process,
- * the working directory and the standard IO streams.
- */
- pub fn new(prog: &str, args: &[~str], options: ProcessOptions) -> Process {
- let ProcessOptions { env, dir, in_fd, out_fd, err_fd } = options;
- let env = env.as_ref().map(|a| a.as_slice());
- let cwd = dir.as_ref().map(|a| a.as_str().unwrap());
- fn rtify(fd: Option<c_int>, input: bool) -> process::StdioContainer {
- match fd {
- Some(fd) => process::InheritFd(fd),
- None => process::CreatePipe(input, !input),
- }
- }
- let rtio = [rtify(in_fd, true), rtify(out_fd, false),
- rtify(err_fd, false)];
- let rtconfig = process::ProcessConfig {
- program: prog,
- args: args,
- env: env,
- cwd: cwd,
- io: rtio,
- };
- let inner = process::Process::new(rtconfig).unwrap();
- Process { inner: inner }
- }
-
- /// Returns the unique id of the process
- pub fn get_id(&self) -> pid_t { self.inner.id() }
-
- /**
- * Returns an io::Writer that can be used to write to this Process's stdin.
- *
- * Fails if there is no stdin available (it's already been removed by
- * take_input)
- */
- pub fn input<'a>(&'a mut self) -> &'a mut io::Writer {
- self.inner.io[0].get_mut_ref() as &mut io::Writer
- }
-
- /**
- * Returns an io::Reader that can be used to read from this Process's stdout.
- *
- * Fails if there is no stdout available (it's already been removed by
- * take_output)
- */
- pub fn output<'a>(&'a mut self) -> &'a mut io::Reader {
- self.inner.io[1].get_mut_ref() as &mut io::Reader
- }
-
- /**
- * Returns an io::Reader that can be used to read from this Process's stderr.
- *
- * Fails if there is no stderr available (it's already been removed by
- * take_error)
- */
- pub fn error<'a>(&'a mut self) -> &'a mut io::Reader {
- self.inner.io[2].get_mut_ref() as &mut io::Reader
- }
-
- /**
- * Closes the handle to the child process's stdin.
- */
- pub fn close_input(&mut self) {
- self.inner.io[0].take();
- }
-
- fn close_outputs(&mut self) {
- self.inner.io[1].take();
- self.inner.io[2].take();
- }
-
- /**
- * Closes the handle to stdin, waits for the child process to terminate,
- * and returns the exit code.
- *
- * If the child has already been finished then the exit code is returned.
- */
- pub fn finish(&mut self) -> ProcessExit { self.inner.wait() }
-
- /**
- * Closes the handle to stdin, waits for the child process to terminate, and
- * reads and returns all remaining output of stdout and stderr, along with
- * the exit code.
- *
- * If the child has already been finished then the exit code and any
- * remaining unread output of stdout and stderr will be returned.
- *
- * This method will fail if the child process's stdout or stderr streams
- * were redirected to existing file descriptors.
- */
- pub fn finish_with_output(&mut self) -> ProcessOutput {
- self.close_input();
- let output = Cell::new(self.inner.io[1].take());
- let error = Cell::new(self.inner.io[2].take());
-
- // Spawn two entire schedulers to read both stdout and sterr
- // in parallel so we don't deadlock while blocking on one
- // or the other. FIXME (#2625): Surely there's a much more
- // clever way to do this.
- let (p, ch) = stream();
- let ch = SharedChan::new(ch);
- let ch_clone = ch.clone();
-
- do spawn {
- io::ignore_io_error(|| {
- match error.take() {
- Some(ref mut e) => ch.send((2, e.read_to_end())),
- None => ch.send((2, ~[]))
- }
- })
- }
- do spawn {
- io::ignore_io_error(|| {
- match output.take() {
- Some(ref mut e) => ch_clone.send((1, e.read_to_end())),
- None => ch_clone.send((1, ~[]))
- }
- })
- }
-
- let status = self.finish();
-
- let (errs, outs) = match (p.recv(), p.recv()) {
- ((1, o), (2, e)) => (e, o),
- ((2, e), (1, o)) => (e, o),
- ((x, _), (y, _)) => {
- fail!("unexpected file numbers: {}, {}", x, y);
- }
- };
-
- return ProcessOutput {status: status,
- output: outs,
- error: errs};
- }
-
- /**
- * Terminates the process, giving it a chance to clean itself up if
- * this is supported by the operating system.
- *
- * On Posix OSs SIGTERM will be sent to the process. On Win32
- * TerminateProcess(..) will be called.
- */
- pub fn destroy(&mut self) {
- self.inner.signal(io::process::PleaseExitSignal);
- self.finish();
- }
-
- /**
- * Terminates the process as soon as possible without giving it a
- * chance to clean itself up.
- *
- * On Posix OSs SIGKILL will be sent to the process. On Win32
- * TerminateProcess(..) will be called.
- */
- pub fn force_destroy(&mut self) {
- self.inner.signal(io::process::MustDieSignal);
- self.finish();
- }
-}
-
-/**
- * Spawns a process and waits for it to terminate. The process will
- * inherit the current stdin/stdout/stderr file descriptors.
- *
- * # Arguments
- *
- * * prog - The path to an executable
- * * args - Vector of arguments to pass to the child process
- *
- * # Return value
- *
- * The process's exit code
- */
-pub fn process_status(prog: &str, args: &[~str]) -> ProcessExit {
- let mut prog = Process::new(prog, args, ProcessOptions {
- env: None,
- dir: None,
- in_fd: Some(unsafe { libc::dup(libc::STDIN_FILENO) }),
- out_fd: Some(unsafe { libc::dup(libc::STDOUT_FILENO) }),
- err_fd: Some(unsafe { libc::dup(libc::STDERR_FILENO) })
- });
- prog.finish()
-}
-
-/**
- * Spawns a process, records all its output, and waits for it to terminate.
- *
- * # Arguments
- *
- * * prog - The path to an executable
- * * args - Vector of arguments to pass to the child process
- *
- * # Return value
- *
- * The process's stdout/stderr output and exit code.
- */
-pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
- let mut prog = Process::new(prog, args, ProcessOptions::new());
- prog.finish_with_output()
-}
-
-#[cfg(test)]
-mod tests {
- use libc::c_int;
- use option::{Option, None, Some};
- use os;
- use path::Path;
- use run;
- use str;
- use task::spawn;
- use unstable::running_on_valgrind;
- use io::native::file;
- use io::{Writer, Reader};
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_process_status() {
- let mut status = run::process_status("false", []);
- assert!(status.matches_exit_status(1));
-
- status = run::process_status("true", []);
- assert!(status.success());
- }
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_process_output_output() {
-
- let run::ProcessOutput {status, output, error}
- = run::process_output("echo", [~"hello"]);
- let output_str = str::from_utf8(output);
-
- assert!(status.success());
- assert_eq!(output_str.trim().to_owned(), ~"hello");
- // FIXME #7224
- if !running_on_valgrind() {
- assert_eq!(error, ~[]);
- }
- }
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_process_output_error() {
-
- let run::ProcessOutput {status, output, error}
- = run::process_output("mkdir", [~"."]);
-
- assert!(status.matches_exit_status(1));
- assert_eq!(output, ~[]);
- assert!(!error.is_empty());
- }
-
- #[test]
- #[ignore] // FIXME(#10016) cat never sees stdin close
- fn test_pipes() {
-
- let pipe_in = os::pipe();
- let pipe_out = os::pipe();
- let pipe_err = os::pipe();
-
- let mut process = run::Process::new("cat", [], run::ProcessOptions {
- dir: None,
- env: None,
- in_fd: Some(pipe_in.input),
- out_fd: Some(pipe_out.out),
- err_fd: Some(pipe_err.out)
- });
-
- os::close(pipe_in.input);
- os::close(pipe_out.out);
- os::close(pipe_err.out);
-
- do spawn {
- writeclose(pipe_in.out, "test");
- }
- let actual = readclose(pipe_out.input);
- readclose(pipe_err.input);
- process.finish();
-
- assert_eq!(~"test", actual);
- }
-
- fn writeclose(fd: c_int, s: &str) {
- let mut writer = file::FileDesc::new(fd, true);
- writer.write(s.as_bytes());
- }
-
- fn readclose(fd: c_int) -> ~str {
- let mut res = ~[];
- let mut reader = file::FileDesc::new(fd, true);
- let mut buf = [0, ..1024];
- loop {
- match reader.read(buf) {
- Some(n) => { res.push_all(buf.slice_to(n)); }
- None => break
- }
- }
- str::from_utf8_owned(res)
- }
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_finish_once() {
- let mut prog = run::Process::new("false", [], run::ProcessOptions::new());
- assert!(prog.finish().matches_exit_status(1));
- }
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_finish_twice() {
- let mut prog = run::Process::new("false", [], run::ProcessOptions::new());
- assert!(prog.finish().matches_exit_status(1));
- assert!(prog.finish().matches_exit_status(1));
- }
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_finish_with_output_once() {
-
- let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new());
- let run::ProcessOutput {status, output, error}
- = prog.finish_with_output();
- let output_str = str::from_utf8(output);
-
- assert!(status.success());
- assert_eq!(output_str.trim().to_owned(), ~"hello");
- // FIXME #7224
- if !running_on_valgrind() {
- assert_eq!(error, ~[]);
- }
- }
-
- #[test]
- #[cfg(not(target_os="android"))] // FIXME(#10380)
- fn test_finish_with_output_twice() {
-
- let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new());
- let run::ProcessOutput {status, output, error}
- = prog.finish_with_output();
-
- let output_str = str::from_utf8(output);
-
- assert!(status.success());
- assert_eq!(output_str.trim().to_owned(), ~"hello");
- // FIXME #7224
- if !running_on_valgrind() {
- assert_eq!(error, ~[]);
- }
-
- let run::ProcessOutput {status, output, error}
- = prog.finish_with_output();
-
- assert!(status.success());
- assert_eq!(output, ~[]);
- // FIXME #7224
- if !running_on_valgrind() {
- assert_eq!(error, ~[]);
- }
- }
-
- #[cfg(unix,not(target_os="android"))]
- fn run_pwd(dir: Option<&Path>) -> run::Process {
- run::Process::new("pwd", [], run::ProcessOptions {
- dir: dir,
- .. run::ProcessOptions::new()
- })
- }
- #[cfg(unix,target_os="android")]
- fn run_pwd(dir: Option<&Path>) -> run::Process {
- run::Process::new("/system/bin/sh", [~"-c",~"pwd"], run::ProcessOptions {
- dir: dir,
- .. run::ProcessOptions::new()
- })
- }
-
- #[cfg(windows)]
- fn run_pwd(dir: Option<&Path>) -> run::Process {
- run::Process::new("cmd", [~"/c", ~"cd"], run::ProcessOptions {
- dir: dir,
- .. run::ProcessOptions::new()
- })
- }
-
- #[test]
- fn test_keep_current_working_dir() {
- let mut prog = run_pwd(None);
-
- let output = str::from_utf8(prog.finish_with_output().output);
- let parent_dir = os::getcwd();
- let child_dir = Path::new(output.trim());
-
- let parent_stat = parent_dir.stat();
- let child_stat = child_dir.stat();
-
- assert_eq!(parent_stat.unstable.device, child_stat.unstable.device);
- assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
- }
-
- #[test]
- fn test_change_working_directory() {
- // test changing to the parent of os::getcwd() because we know
- // the path exists (and os::getcwd() is not expected to be root)
- let parent_dir = os::getcwd().dir_path();
- let mut prog = run_pwd(Some(&parent_dir));
-
- let output = str::from_utf8(prog.finish_with_output().output);
- let child_dir = Path::new(output.trim());
-
- let parent_stat = parent_dir.stat();
- let child_stat = child_dir.stat();
-
- assert_eq!(parent_stat.unstable.device, child_stat.unstable.device);
- assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
- }
-
- #[cfg(unix,not(target_os="android"))]
- fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
- run::Process::new("env", [], run::ProcessOptions {
- env: env,
- .. run::ProcessOptions::new()
- })
- }
- #[cfg(unix,target_os="android")]
- fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
- run::Process::new("/system/bin/sh", [~"-c",~"set"], run::ProcessOptions {
- env: env,
- .. run::ProcessOptions::new()
- })
- }
-
- #[cfg(windows)]
- fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
- run::Process::new("cmd", [~"/c", ~"set"], run::ProcessOptions {
- env: env,
- .. run::ProcessOptions::new()
- })
- }
-
- #[test]
- #[cfg(not(target_os="android"))]
- fn test_inherit_env() {
- if running_on_valgrind() { return; }
-
- let mut prog = run_env(None);
- let output = str::from_utf8(prog.finish_with_output().output);
-
- let r = os::env();
- for &(ref k, ref v) in r.iter() {
- // don't check windows magical empty-named variables
- assert!(k.is_empty() || output.contains(format!("{}={}", *k, *v)));
- }
- }
- #[test]
- #[cfg(target_os="android")]
- fn test_inherit_env() {
- if running_on_valgrind() { return; }
-
- let mut prog = run_env(None);
- let output = str::from_utf8(prog.finish_with_output().output);
-
- let r = os::env();
- for &(ref k, ref v) in r.iter() {
- // don't check android RANDOM variables
- if *k != ~"RANDOM" {
- assert!(output.contains(format!("{}={}", *k, *v)) ||
- output.contains(format!("{}=\'{}\'", *k, *v)));
- }
- }
- }
-
- #[test]
- fn test_add_to_env() {
-
- let mut new_env = os::env();
- new_env.push((~"RUN_TEST_NEW_ENV", ~"123"));
-
- let mut prog = run_env(Some(new_env));
- let output = str::from_utf8(prog.finish_with_output().output);
-
- assert!(output.contains("RUN_TEST_NEW_ENV=123"));
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[allow(missing_doc)];
-
-use cell::Cell;
-use comm;
-use container::Container;
-use iter::{Iterator, DoubleEndedIterator};
-use option::*;
-// use either::{Either, Left, Right};
-// use rt::kill::BlockedTask;
-use rt::local::Local;
-use rt::rtio::EventLoop;
-use rt::sched::Scheduler;
-use rt::shouldnt_be_public::{SelectInner, SelectPortInner};
-use unstable::finally::Finally;
-use vec::{OwnedVector, MutableVector};
-
-/// Trait for message-passing primitives that can be select()ed on.
-pub trait Select : SelectInner { }
-
-/// Trait for message-passing primitives that can use the select2() convenience wrapper.
-// (This is separate from the above trait to enable heterogeneous lists of ports
-// that implement Select on different types to use select().)
-pub trait SelectPort<T> : SelectPortInner<T> { }
-
-/// Receive a message from any one of many ports at once. Returns the index of the
-/// port whose data is ready. (If multiple are ready, returns the lowest index.)
-pub fn select<A: Select>(ports: &mut [A]) -> uint {
- if ports.is_empty() {
- fail!("can't select on an empty list");
- }
-
- for (index, port) in ports.mut_iter().enumerate() {
- if port.optimistic_check() {
- return index;
- }
- }
-
- // If one of the ports already contains data when we go to block on it, we
- // don't bother enqueueing on the rest of them, so we shouldn't bother
- // unblocking from it either. This is just for efficiency, not correctness.
- // (If not, we need to unblock from all of them. Length is a placeholder.)
- let mut ready_index = ports.len();
-
- // XXX: We're using deschedule...and_then in an unsafe way here (see #8132),
- // in that we need to continue mutating the ready_index in the environment
- // after letting the task get woken up. The and_then closure needs to delay
- // the task from resuming until all ports have become blocked_on.
- let (p,c) = comm::oneshot();
- let p = Cell::new(p);
- let c = Cell::new(c);
-
- (|| {
- let c = Cell::new(c.take());
- let sched: ~Scheduler = Local::take();
- sched.deschedule_running_task_and_then(|sched, task| {
- let task_handles = task.make_selectable(ports.len());
-
- for (index, (port, task_handle)) in
- ports.mut_iter().zip(task_handles.move_iter()).enumerate() {
- // If one of the ports has data by now, it will wake the handle.
- if port.block_on(sched, task_handle) {
- ready_index = index;
- break;
- }
- }
-
- let c = Cell::new(c.take());
- do sched.event_loop.callback { c.take().send_deferred(()) }
- })
- }).finally(|| {
- // Unkillable is necessary not because getting killed is dangerous here,
- // but to force the recv not to use the same kill-flag that we used for
- // selecting. Otherwise a user-sender could spuriously wakeup us here.
- p.take().recv();
- });
-
- // Task resumes. Now unblock ourselves from all the ports we blocked on.
- // If the success index wasn't reset, 'take' will just take all of them.
- // Iterate in reverse so the 'earliest' index that's ready gets returned.
- for (index, port) in ports.mut_slice(0, ready_index).mut_iter().enumerate().invert() {
- if port.unblock_from() {
- ready_index = index;
- }
- }
-
- assert!(ready_index < ports.len());
- return ready_index;
-}
-
-/* FIXME(#5121, #7914) This all should be legal, but rust is not clever enough yet.
-
-impl <'self> Select for &'self mut Select {
- fn optimistic_check(&mut self) -> bool { self.optimistic_check() }
- fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
- self.block_on(sched, task)
- }
- fn unblock_from(&mut self) -> bool { self.unblock_from() }
-}
-
-pub fn select2<TA, A: SelectPort<TA>, TB, B: SelectPort<TB>>(mut a: A, mut b: B)
- -> Either<(Option<TA>, B), (A, Option<TB>)> {
- let result = {
- let mut ports = [&mut a as &mut Select, &mut b as &mut Select];
- select(ports)
- };
- match result {
- 0 => Left ((a.recv_ready(), b)),
- 1 => Right((a, b.recv_ready())),
- x => fail!("impossible case in select2: {:?}", x)
- }
-}
-
-*/
-
-#[cfg(test)]
-mod test {
- use super::*;
- use clone::Clone;
- use num::Times;
- use option::*;
- use rt::comm::*;
- use rt::test::*;
- use vec::*;
- use comm::GenericChan;
- use task;
- use cell::Cell;
- use iter::{Iterator, range};
-
- #[test] #[should_fail]
- fn select_doesnt_get_trolled() {
- select::<PortOne<()>>([]);
- }
-
- /* non-blocking select tests */
-
- #[cfg(test)]
- fn select_helper(num_ports: uint, send_on_chans: &[uint]) {
- // Unfortunately this does not actually test the block_on early-break
- // codepath in select -- racing between the sender and the receiver in
- // separate tasks is necessary to get around the optimistic check.
- let (ports, chans) = unzip(range(0, num_ports).map(|_| oneshot::<()>()));
- let mut dead_chans = ~[];
- let mut ports = ports;
- for (i, chan) in chans.move_iter().enumerate() {
- if send_on_chans.contains(&i) {
- chan.send(());
- } else {
- dead_chans.push(chan);
- }
- }
- let ready_index = select(ports);
- assert!(send_on_chans.contains(&ready_index));
- assert!(ports.swap_remove(ready_index).recv_ready().is_some());
- let _ = dead_chans;
-
- // Same thing with streams instead.
- // FIXME(#7971): This should be in a macro but borrowck isn't smart enough.
- let (ports, chans) = unzip(range(0, num_ports).map(|_| stream::<()>()));
- let mut dead_chans = ~[];
- let mut ports = ports;
- for (i, chan) in chans.move_iter().enumerate() {
- if send_on_chans.contains(&i) {
- chan.send(());
- } else {
- dead_chans.push(chan);
- }
- }
- let ready_index = select(ports);
- assert!(send_on_chans.contains(&ready_index));
- assert!(ports.swap_remove(ready_index).recv_ready().is_some());
- let _ = dead_chans;
- }
-
- #[test]
- fn select_one() {
- do run_in_uv_task { select_helper(1, [0]) }
- }
-
- #[test]
- fn select_two() {
- // NB. I would like to have a test that tests the first one that is
- // ready is the one that's returned, but that can't be reliably tested
- // with the randomized behaviour of optimistic_check.
- do run_in_uv_task { select_helper(2, [1]) }
- do run_in_uv_task { select_helper(2, [0]) }
- do run_in_uv_task { select_helper(2, [1,0]) }
- }
-
- #[test]
- fn select_a_lot() {
- do run_in_uv_task { select_helper(12, [7,8,9]) }
- }
-
- #[test]
- fn select_stream() {
- use util;
- use comm::GenericChan;
-
- // Sends 10 buffered packets, and uses select to retrieve them all.
- // Puts the port in a different spot in the vector each time.
- do run_in_uv_task {
- let (ports, _) = unzip(range(0u, 10).map(|_| stream::<int>()));
- let (port, chan) = stream();
- 10.times(|| { chan.send(31337); });
- let mut ports = ports;
- let mut port = Some(port);
- let order = [5u,0,4,3,2,6,9,8,7,1];
- for &index in order.iter() {
- // put the port in the vector at any index
- util::swap(port.get_mut_ref(), &mut ports[index]);
- assert!(select(ports) == index);
- // get it back out
- util::swap(port.get_mut_ref(), &mut ports[index]);
- // NB. Not recv(), because optimistic_check randomly fails.
- assert!(port.get_ref().recv_ready().unwrap() == 31337);
- }
- }
- }
-
- #[test]
- fn select_simple() {
- do run_in_uv_task {
- select_helper(2, [1])
- }
- }
-
- /* blocking select tests */
-
- #[test]
- fn select_blocking() {
- do run_in_uv_task {
- let (p1,_c) = oneshot();
- let (p2,c2) = oneshot();
- let mut ports = [p1,p2];
-
- let (p3,c3) = oneshot();
- let (p4,c4) = oneshot();
-
- let x = Cell::new((c2, p3, c4));
- do task::spawn {
- let (c2, p3, c4) = x.take();
- p3.recv(); // handshake parent
- c4.send(()); // normal receive
- task::deschedule();
- c2.send(()); // select receive
- }
-
- // Try to block before child sends on c2.
- c3.send(());
- p4.recv();
- assert!(select(ports) == 1);
- }
- }
-
- #[test]
- fn select_racing_senders() {
- static NUM_CHANS: uint = 10;
-
- select_racing_senders_helper(~[0,1,2,3,4,5,6,7,8,9]);
- select_racing_senders_helper(~[0,1,2]);
- select_racing_senders_helper(~[3,4,5,6]);
- select_racing_senders_helper(~[7,8,9]);
-
- fn select_racing_senders_helper(send_on_chans: ~[uint]) {
- use rt::test::spawntask_random;
-
- do run_in_uv_task {
- // A bit of stress, since ordinarily this is just smoke and mirrors.
- 4.times(|| {
- let send_on_chans = send_on_chans.clone();
- do task::spawn {
- let mut ports = ~[];
- for i in range(0u, NUM_CHANS) {
- let (p,c) = oneshot();
- ports.push(p);
- if send_on_chans.contains(&i) {
- let c = Cell::new(c);
- do spawntask_random {
- task::deschedule();
- c.take().send(());
- }
- }
- }
- // nondeterministic result, but should succeed
- select(ports);
- }
- })
- }
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! `SendStr` definition and trait implementations
-
-use clone::{Clone, DeepClone};
-use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv};
-use cmp::Ordering;
-use container::Container;
-use default::Default;
-use str::{Str, StrSlice};
-use to_str::ToStr;
-use to_bytes::{IterBytes, Cb};
-
-/// A SendStr is a string that can hold either a ~str or a &'static str.
-/// This can be useful as an optimization when an allocation is sometimes
-/// needed but the common case is statically known.
-#[allow(missing_doc)]
-pub enum SendStr {
- SendStrOwned(~str),
- SendStrStatic(&'static str)
-}
-
-impl SendStr {
- /// Returns `true` if this `SendStr` wraps an owned string
- #[inline]
- pub fn is_owned(&self) -> bool {
- match *self {
- SendStrOwned(_) => true,
- SendStrStatic(_) => false
- }
- }
-
- /// Returns `true` if this `SendStr` wraps an static string
- #[inline]
- pub fn is_static(&self) -> bool {
- match *self {
- SendStrOwned(_) => false,
- SendStrStatic(_) => true
- }
- }
-}
-
-/// Trait for moving into an `SendStr`
-pub trait IntoSendStr {
- /// Moves self into an `SendStr`
- fn into_send_str(self) -> SendStr;
-}
-
-impl IntoSendStr for ~str {
- #[inline]
- fn into_send_str(self) -> SendStr { SendStrOwned(self) }
-}
-
-impl IntoSendStr for &'static str {
- #[inline]
- fn into_send_str(self) -> SendStr { SendStrStatic(self) }
-}
-
-impl IntoSendStr for SendStr {
- #[inline]
- fn into_send_str(self) -> SendStr { self }
-}
-
-/*
-Section: String trait impls.
-`SendStr` should behave like a normal string, so we don't derive.
-*/
-
-impl ToStr for SendStr {
- #[inline]
- fn to_str(&self) -> ~str { self.as_slice().to_owned() }
-}
-
-impl Eq for SendStr {
- #[inline]
- fn eq(&self, other: &SendStr) -> bool {
- self.as_slice().equals(&other.as_slice())
- }
-}
-
-impl TotalEq for SendStr {
- #[inline]
- fn equals(&self, other: &SendStr) -> bool {
- self.as_slice().equals(&other.as_slice())
- }
-}
-
-impl Ord for SendStr {
- #[inline]
- fn lt(&self, other: &SendStr) -> bool {
- self.as_slice().lt(&other.as_slice())
- }
-}
-
-impl TotalOrd for SendStr {
- #[inline]
- fn cmp(&self, other: &SendStr) -> Ordering {
- self.as_slice().cmp(&other.as_slice())
- }
-}
-
-impl<'self, S: Str> Equiv<S> for SendStr {
- #[inline]
- fn equiv(&self, other: &S) -> bool {
- self.as_slice().equals(&other.as_slice())
- }
-}
-
-impl Str for SendStr {
- #[inline]
- fn as_slice<'r>(&'r self) -> &'r str {
- match *self {
- SendStrOwned(ref s) => s.as_slice(),
- // XXX: Borrowchecker doesn't recognize lifetime as static unless prompted
- // SendStrStatic(s) => s.as_slice()
- SendStrStatic(s) => {let tmp: &'static str = s; tmp}
- }
- }
-
- #[inline]
- fn into_owned(self) -> ~str {
- match self {
- SendStrOwned(s) => s,
- SendStrStatic(s) => s.to_owned()
- }
- }
-}
-
-impl Container for SendStr {
- #[inline]
- fn len(&self) -> uint { self.as_slice().len() }
-}
-
-impl Clone for SendStr {
- #[inline]
- fn clone(&self) -> SendStr {
- match *self {
- SendStrOwned(ref s) => SendStrOwned(s.to_owned()),
- SendStrStatic(s) => SendStrStatic(s)
- }
- }
-}
-
-impl DeepClone for SendStr {
- #[inline]
- fn deep_clone(&self) -> SendStr {
- match *self {
- SendStrOwned(ref s) => SendStrOwned(s.to_owned()),
- SendStrStatic(s) => SendStrStatic(s)
- }
- }
-}
-
-impl Default for SendStr {
- #[inline]
- fn default() -> SendStr { SendStrStatic("") }
-}
-
-impl IterBytes for SendStr {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- match *self {
- SendStrOwned(ref s) => s.iter_bytes(lsb0, f),
- SendStrStatic(s) => s.iter_bytes(lsb0, f)
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use clone::{Clone, DeepClone};
- use cmp::{TotalEq, Ord, TotalOrd, Equiv};
- use cmp::Equal;
- use container::Container;
- use default::Default;
- use send_str::{SendStrOwned, SendStrStatic};
- use str::Str;
- use to_str::ToStr;
-
- #[test]
- fn test_send_str_traits() {
- let s = SendStrStatic("abcde");
- assert_eq!(s.len(), 5);
- assert_eq!(s.as_slice(), "abcde");
- assert_eq!(s.to_str(), ~"abcde");
- assert!(s.equiv(&@"abcde"));
- assert!(s.lt(&SendStrOwned(~"bcdef")));
- assert_eq!(SendStrStatic(""), Default::default());
-
- let o = SendStrOwned(~"abcde");
- assert_eq!(o.len(), 5);
- assert_eq!(o.as_slice(), "abcde");
- assert_eq!(o.to_str(), ~"abcde");
- assert!(o.equiv(&@"abcde"));
- assert!(o.lt(&SendStrStatic("bcdef")));
- assert_eq!(SendStrOwned(~""), Default::default());
-
- assert_eq!(s.cmp(&o), Equal);
- assert!(s.equals(&o));
- assert!(s.equiv(&o));
-
- assert_eq!(o.cmp(&s), Equal);
- assert!(o.equals(&s));
- assert!(o.equiv(&s));
- }
-
- #[test]
- fn test_send_str_methods() {
- let s = SendStrStatic("abcde");
- assert!(s.is_static());
- assert!(!s.is_owned());
-
- let o = SendStrOwned(~"abcde");
- assert!(!o.is_static());
- assert!(o.is_owned());
- }
-
- #[test]
- fn test_send_str_clone() {
- assert_eq!(SendStrOwned(~"abcde"), SendStrStatic("abcde").clone());
- assert_eq!(SendStrOwned(~"abcde"), SendStrStatic("abcde").deep_clone());
-
- assert_eq!(SendStrOwned(~"abcde"), SendStrOwned(~"abcde").clone());
- assert_eq!(SendStrOwned(~"abcde"), SendStrOwned(~"abcde").deep_clone());
-
- assert_eq!(SendStrStatic("abcde"), SendStrStatic("abcde").clone());
- assert_eq!(SendStrStatic("abcde"), SendStrStatic("abcde").deep_clone());
-
- assert_eq!(SendStrStatic("abcde"), SendStrOwned(~"abcde").clone());
- assert_eq!(SendStrStatic("abcde"), SendStrOwned(~"abcde").deep_clone());
- }
-
- #[test]
- fn test_send_str_into_owned() {
- assert_eq!(SendStrStatic("abcde").into_owned(), ~"abcde");
- assert_eq!(SendStrOwned(~"abcde").into_owned(), ~"abcde");
- }
-
- #[test]
- fn test_into_send_str() {
- assert_eq!("abcde".into_send_str(), SendStrStatic("abcde"));
- assert_eq!((~"abcde").into_send_str(), SendStrStatic("abcde"));
- assert_eq!("abcde".into_send_str(), SendStrOwned(~"abcde"));
- assert_eq!((~"abcde").into_send_str(), SendStrOwned(~"abcde"));
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-String manipulation
-
-# Basic Usage
-
-Rust's string type is one of the core primitive types of the language. While
-represented by the name `str`, the name `str` is not actually a valid type in
-Rust. Each string must also be decorated with its ownership. This means that
-there are three common kinds of strings in rust:
-
-* `~str` - This is an owned string. This type obeys all of the normal semantics
- of the `~T` types, meaning that it has one, and only one, owner. This
- type cannot be implicitly copied, and is moved out of when passed to
- other functions.
-
-* `@str` - This is a managed string. Similarly to `@T`, this type can be
- implicitly copied, and each implicit copy will increment the
- reference count to the string. This means that there is no "true
- owner" of the string, and the string will be deallocated when the
- reference count reaches 0.
-
-* `&str` - Finally, this is the borrowed string type. This type of string can
- only be created from one of the other two kinds of strings. As the
- name "borrowed" implies, this type of string is owned elsewhere, and
- this string cannot be moved out of.
-
-As an example, here's a few different kinds of strings.
-
-```rust
-let owned_string = ~"I am an owned string";
-let managed_string = @"This string is garbage-collected";
-let borrowed_string1 = "This string is borrowed with the 'static lifetime";
-let borrowed_string2: &str = owned_string; // owned strings can be borrowed
-let borrowed_string3: &str = managed_string; // managed strings can also be borrowed
- ```
-
-From the example above, you can see that rust has 3 different kinds of string
-literals. The owned/managed literals correspond to the owned/managed string
-types, but the "borrowed literal" is actually more akin to C's concept of a
-static string.
-
-When a string is declared without a `~` or `@` sigil, then the string is
-allocated statically in the rodata of the executable/library. The string then
-has the type `&'static str` meaning that the string is valid for the `'static`
-lifetime, otherwise known as the lifetime of the entire program. As can be
-inferred from the type, these static strings are not mutable.
-
-# Mutability
-
-Many languages have immutable strings by default, and rust has a particular
-flavor on this idea. As with the rest of Rust types, strings are immutable by
-default. If a string is declared as `mut`, however, it may be mutated. This
-works the same way as the rest of Rust's type system in the sense that if
-there's a mutable reference to a string, there may only be one mutable reference
-to that string. With these guarantees, strings can easily transition between
-being mutable/immutable with the same benefits of having mutable strings in
-other languages.
-
-```rust
-let mut buf = ~"testing";
-buf.push_char(' ');
-buf.push_str("123");
-assert_eq!(buf, ~"testing 123");
- ```
-
-# Representation
-
-Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
-stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
-encoded UTF-8 sequences. Additionally, strings are not null-terminated
-and can contain null codepoints.
-
-The actual representation of strings have direct mappings to vectors:
-
-* `~str` is the same as `~[u8]`
-* `&str` is the same as `&[u8]`
-* `@str` is the same as `@[u8]`
-
-*/
-
-use at_vec;
-use cast;
-use cast::transmute;
-use char;
-use char::Char;
-use clone::{Clone, DeepClone};
-use container::{Container, Mutable};
-use iter::{Iterator, FromIterator, Extendable, range};
-use iter::{Filter, AdditiveIterator, Map};
-use iter::{Invert, DoubleEndedIterator, ExactSize};
-use libc;
-use num::{Saturating};
-use option::{None, Option, Some};
-use ptr;
-use ptr::RawPtr;
-use to_str::ToStr;
-use from_str::FromStr;
-use uint;
-use vec;
-use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector, MutableVector};
-use default::Default;
-use send_str::{SendStr, SendStrOwned};
-
-/*
-Section: Conditions
-*/
-
-condition! {
- pub not_utf8: (~str) -> ~str;
-}
-
-/*
-Section: Creating a string
-*/
-
-/// Convert a vector of bytes to a new UTF-8 string
-///
-/// # Failure
-///
-/// Raises the `not_utf8` condition if invalid UTF-8
-pub fn from_utf8(vv: &[u8]) -> ~str {
- use str::not_utf8::cond;
-
- match from_utf8_opt(vv) {
- None => {
- let first_bad_byte = *vv.iter().find(|&b| !is_utf8([*b])).unwrap();
- cond.raise(format!("from_utf8: input is not UTF-8; first bad \
- byte is {}", first_bad_byte))
- }
- Some(s) => s
- }
-}
-
-/// Convert a vector of bytes to a new UTF-8 string, if possible.
-/// Returns None if the vector contains invalid UTF-8.
-pub fn from_utf8_opt(vv: &[u8]) -> Option<~str> {
- if is_utf8(vv) {
- Some(unsafe { raw::from_utf8(vv) })
- } else {
- None
- }
-}
-
-/// Consumes a vector of bytes to create a new utf-8 string
-///
-/// # Failure
-///
-/// Raises the `not_utf8` condition if invalid UTF-8
-pub fn from_utf8_owned(vv: ~[u8]) -> ~str {
- use str::not_utf8::cond;
-
- if !is_utf8(vv) {
- let first_bad_byte = *vv.iter().find(|&b| !is_utf8([*b])).unwrap();
- cond.raise(format!("from_utf8: input is not UTF-8; first bad byte is {}",
- first_bad_byte))
- } else {
- unsafe { raw::from_utf8_owned(vv) }
- }
-}
-
-/// Consumes a vector of bytes to create a new utf-8 string.
-/// Returns None if the vector contains invalid UTF-8.
-pub fn from_utf8_owned_opt(vv: ~[u8]) -> Option<~str> {
- if is_utf8(vv) {
- Some(unsafe { raw::from_utf8_owned(vv) })
- } else {
- None
- }
-}
-
-/// Converts a vector to a string slice without performing any allocations.
-///
-/// Once the slice has been validated as utf-8, it is transmuted in-place and
-/// returned as a '&str' instead of a '&[u8]'
-///
-/// # Failure
-///
-/// Fails if invalid UTF-8
-pub fn from_utf8_slice<'a>(v: &'a [u8]) -> &'a str {
- from_utf8_slice_opt(v).expect("from_utf8_slice: not utf-8")
-}
-
-/// Converts a vector to a string slice without performing any allocations.
-///
-/// Returns None if the slice is not utf-8.
-pub fn from_utf8_slice_opt<'a>(v: &'a [u8]) -> Option<&'a str> {
- if is_utf8(v) {
- Some(unsafe { cast::transmute(v) })
- } else { None }
-}
-
-impl ToStr for ~str {
- #[inline]
- fn to_str(&self) -> ~str { self.to_owned() }
-}
-
-impl FromStr for ~str {
- #[inline]
- fn from_str(s: &str) -> Option<~str> { Some(s.to_owned()) }
-}
-
-impl<'self> ToStr for &'self str {
- #[inline]
- fn to_str(&self) -> ~str { self.to_owned() }
-}
-
-impl ToStr for @str {
- #[inline]
- fn to_str(&self) -> ~str { self.to_owned() }
-}
-
-impl<'self> FromStr for @str {
- #[inline]
- fn from_str(s: &str) -> Option<@str> { Some(s.to_managed()) }
-}
-
-/// Convert a byte to a UTF-8 string
-///
-/// # Failure
-///
-/// Fails if invalid UTF-8
-pub fn from_byte(b: u8) -> ~str {
- assert!(b < 128u8);
- unsafe { ::cast::transmute(~[b]) }
-}
-
-/// Convert a char to a string
-pub fn from_char(ch: char) -> ~str {
- let mut buf = ~"";
- buf.push_char(ch);
- buf
-}
-
-/// Convert a vector of chars to a string
-pub fn from_chars(chs: &[char]) -> ~str {
- let mut buf = ~"";
- buf.reserve(chs.len());
- for ch in chs.iter() {
- buf.push_char(*ch)
- }
- buf
-}
-
-#[doc(hidden)]
-pub fn push_str(lhs: &mut ~str, rhs: &str) {
- lhs.push_str(rhs)
-}
-
-/// Methods for vectors of strings
-pub trait StrVector {
- /// Concatenate a vector of strings.
- fn concat(&self) -> ~str;
-
- /// Concatenate a vector of strings, placing a given separator between each.
- fn connect(&self, sep: &str) -> ~str;
-}
-
-impl<'self, S: Str> StrVector for &'self [S] {
- fn concat(&self) -> ~str {
- if self.is_empty() { return ~""; }
-
- // `len` calculation may overflow but push_str but will check boundaries
- let len = self.iter().map(|s| s.as_slice().len()).sum();
-
- let mut result = with_capacity(len);
-
- for s in self.iter() {
- result.push_str(s.as_slice())
- }
- result
- }
-
- fn connect(&self, sep: &str) -> ~str {
- if self.is_empty() { return ~""; }
-
- // concat is faster
- if sep.is_empty() { return self.concat(); }
-
- // this is wrong without the guarantee that `self` is non-empty
- // `len` calculation may overflow but push_str but will check boundaries
- let len = sep.len() * (self.len() - 1)
- + self.iter().map(|s| s.as_slice().len()).sum();
- let mut result = with_capacity(len);
- let mut first = true;
-
- for s in self.iter() {
- if first {
- first = false;
- } else {
- result.push_str(sep);
- }
- result.push_str(s.as_slice());
- }
- result
- }
-}
-
-/// Something that can be used to compare against a character
-pub trait CharEq {
- /// Determine if the splitter should split at the given character
- fn matches(&self, char) -> bool;
- /// Indicate if this is only concerned about ASCII characters,
- /// which can allow for a faster implementation.
- fn only_ascii(&self) -> bool;
-}
-
-impl CharEq for char {
- #[inline]
- fn matches(&self, c: char) -> bool { *self == c }
-
- fn only_ascii(&self) -> bool { (*self as uint) < 128 }
-}
-
-impl<'self> CharEq for 'self |char| -> bool {
- #[inline]
- fn matches(&self, c: char) -> bool { (*self)(c) }
-
- fn only_ascii(&self) -> bool { false }
-}
-
-impl CharEq for extern "Rust" fn(char) -> bool {
- #[inline]
- fn matches(&self, c: char) -> bool { (*self)(c) }
-
- fn only_ascii(&self) -> bool { false }
-}
-
-impl<'self, C: CharEq> CharEq for &'self [C] {
- #[inline]
- fn matches(&self, c: char) -> bool {
- self.iter().any(|m| m.matches(c))
- }
-
- fn only_ascii(&self) -> bool {
- self.iter().all(|m| m.only_ascii())
- }
-}
-
-/*
-Section: Iterators
-*/
-
-/// External iterator for a string's characters.
-/// Use with the `std::iter` module.
-#[deriving(Clone)]
-pub struct CharIterator<'self> {
- /// The slice remaining to be iterated
- priv string: &'self str,
-}
-
-impl<'self> Iterator<char> for CharIterator<'self> {
- #[inline]
- fn next(&mut self) -> Option<char> {
- // Decode the next codepoint, then update
- // the slice to be just the remaining part
- if self.string.len() != 0 {
- let CharRange {ch, next} = self.string.char_range_at(0);
- unsafe {
- self.string = raw::slice_unchecked(self.string, next, self.string.len());
- }
- Some(ch)
- } else {
- None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.string.len().saturating_add(3)/4, Some(self.string.len()))
- }
-}
-
-impl<'self> DoubleEndedIterator<char> for CharIterator<'self> {
- #[inline]
- fn next_back(&mut self) -> Option<char> {
- if self.string.len() != 0 {
- let CharRange {ch, next} = self.string.char_range_at_reverse(self.string.len());
- unsafe {
- self.string = raw::slice_unchecked(self.string, 0, next);
- }
- Some(ch)
- } else {
- None
- }
- }
-}
-
-/// External iterator for a string's characters and their byte offsets.
-/// Use with the `std::iter` module.
-#[deriving(Clone)]
-pub struct CharOffsetIterator<'self> {
- /// The original string to be iterated
- priv string: &'self str,
- priv iter: CharIterator<'self>,
-}
-
-impl<'self> Iterator<(uint, char)> for CharOffsetIterator<'self> {
- #[inline]
- fn next(&mut self) -> Option<(uint, char)> {
- // Compute the byte offset by using the pointer offset between
- // the original string slice and the iterator's remaining part
- let offset = self.string.as_imm_buf(|a, _| {
- self.iter.string.as_imm_buf(|b, _| {
- b as uint - a as uint
- })
- });
- self.iter.next().map(|ch| (offset, ch))
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-impl<'self> DoubleEndedIterator<(uint, char)> for CharOffsetIterator<'self> {
- #[inline]
- fn next_back(&mut self) -> Option<(uint, char)> {
- self.iter.next_back().map(|ch| {
- let offset = self.string.as_imm_buf(|a, _| {
- self.iter.string.as_imm_buf(|b, len| {
- b as uint - a as uint + len
- })
- });
- (offset, ch)
- })
- }
-}
-
-/// External iterator for a string's characters in reverse order.
-/// Use with the `std::iter` module.
-pub type CharRevIterator<'self> = Invert<CharIterator<'self>>;
-
-/// External iterator for a string's characters and their byte offsets in reverse order.
-/// Use with the `std::iter` module.
-pub type CharOffsetRevIterator<'self> = Invert<CharOffsetIterator<'self>>;
-
-/// External iterator for a string's bytes.
-/// Use with the `std::iter` module.
-pub type ByteIterator<'self> =
- Map<'self, &'self u8, u8, vec::VecIterator<'self, u8>>;
-
-/// External iterator for a string's bytes in reverse order.
-/// Use with the `std::iter` module.
-pub type ByteRevIterator<'self> = Invert<ByteIterator<'self>>;
-
-/// An iterator over the substrings of a string, separated by `sep`.
-#[deriving(Clone)]
-pub struct CharSplitIterator<'self, Sep> {
- /// The slice remaining to be iterated
- priv string: &'self str,
- priv sep: Sep,
- /// Whether an empty string at the end is allowed
- priv allow_trailing_empty: bool,
- priv only_ascii: bool,
- priv finished: bool,
-}
-
-/// An iterator over the substrings of a string, separated by `sep`,
-/// starting from the back of the string.
-pub type CharRSplitIterator<'self, Sep> = Invert<CharSplitIterator<'self, Sep>>;
-
-/// An iterator over the substrings of a string, separated by `sep`,
-/// splitting at most `count` times.
-#[deriving(Clone)]
-pub struct CharSplitNIterator<'self, Sep> {
- priv iter: CharSplitIterator<'self, Sep>,
- /// The number of splits remaining
- priv count: uint,
- priv invert: bool,
-}
-
-/// An iterator over the words of a string, separated by an sequence of whitespace
-pub type WordIterator<'self> =
- Filter<'self, &'self str, CharSplitIterator<'self, extern "Rust" fn(char) -> bool>>;
-
-/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
-pub type AnyLineIterator<'self> =
- Map<'self, &'self str, &'self str, CharSplitIterator<'self, char>>;
-
-impl<'self, Sep> CharSplitIterator<'self, Sep> {
- #[inline]
- fn get_end(&mut self) -> Option<&'self str> {
- if !self.finished && (self.allow_trailing_empty || self.string.len() > 0) {
- self.finished = true;
- Some(self.string)
- } else {
- None
- }
- }
-}
-
-impl<'self, Sep: CharEq> Iterator<&'self str> for CharSplitIterator<'self, Sep> {
- #[inline]
- fn next(&mut self) -> Option<&'self str> {
- if self.finished { return None }
-
- let mut next_split = None;
- if self.only_ascii {
- for (idx, byte) in self.string.bytes().enumerate() {
- if self.sep.matches(byte as char) && byte < 128u8 {
- next_split = Some((idx, idx + 1));
- break;
- }
- }
- } else {
- for (idx, ch) in self.string.char_indices() {
- if self.sep.matches(ch) {
- next_split = Some((idx, self.string.char_range_at(idx).next));
- break;
- }
- }
- }
- match next_split {
- Some((a, b)) => unsafe {
- let elt = raw::slice_unchecked(self.string, 0, a);
- self.string = raw::slice_unchecked(self.string, b, self.string.len());
- Some(elt)
- },
- None => self.get_end(),
- }
- }
-}
-
-impl<'self, Sep: CharEq> DoubleEndedIterator<&'self str>
-for CharSplitIterator<'self, Sep> {
- #[inline]
- fn next_back(&mut self) -> Option<&'self str> {
- if self.finished { return None }
-
- if !self.allow_trailing_empty {
- self.allow_trailing_empty = true;
- match self.next_back() {
- Some(elt) if !elt.is_empty() => return Some(elt),
- _ => if self.finished { return None }
- }
- }
- let len = self.string.len();
- let mut next_split = None;
-
- if self.only_ascii {
- for (idx, byte) in self.string.bytes().enumerate().invert() {
- if self.sep.matches(byte as char) && byte < 128u8 {
- next_split = Some((idx, idx + 1));
- break;
- }
- }
- } else {
- for (idx, ch) in self.string.char_indices_rev() {
- if self.sep.matches(ch) {
- next_split = Some((idx, self.string.char_range_at(idx).next));
- break;
- }
- }
- }
- match next_split {
- Some((a, b)) => unsafe {
- let elt = raw::slice_unchecked(self.string, b, len);
- self.string = raw::slice_unchecked(self.string, 0, a);
- Some(elt)
- },
- None => { self.finished = true; Some(self.string) }
- }
- }
-}
-
-impl<'self, Sep: CharEq> Iterator<&'self str> for CharSplitNIterator<'self, Sep> {
- #[inline]
- fn next(&mut self) -> Option<&'self str> {
- if self.count != 0 {
- self.count -= 1;
- if self.invert { self.iter.next_back() } else { self.iter.next() }
- } else {
- self.iter.get_end()
- }
- }
-}
-
-/// An iterator over the start and end indices of the matches of a
-/// substring within a larger string
-#[deriving(Clone)]
-pub struct MatchesIndexIterator<'self> {
- priv haystack: &'self str,
- priv needle: &'self str,
- priv position: uint,
-}
-
-/// An iterator over the substrings of a string separated by a given
-/// search string
-#[deriving(Clone)]
-pub struct StrSplitIterator<'self> {
- priv it: MatchesIndexIterator<'self>,
- priv last_end: uint,
- priv finished: bool
-}
-
-impl<'self> Iterator<(uint, uint)> for MatchesIndexIterator<'self> {
- #[inline]
- fn next(&mut self) -> Option<(uint, uint)> {
- // See Issue #1932 for why this is a naive search
- let (h_len, n_len) = (self.haystack.len(), self.needle.len());
- let mut match_start = 0;
- let mut match_i = 0;
-
- while self.position < h_len {
- if self.haystack[self.position] == self.needle[match_i] {
- if match_i == 0 { match_start = self.position; }
- match_i += 1;
- self.position += 1;
-
- if match_i == n_len {
- // found a match!
- return Some((match_start, self.position));
- }
- } else {
- // failed match, backtrack
- if match_i > 0 {
- match_i = 0;
- self.position = match_start;
- }
- self.position += 1;
- }
- }
- None
- }
-}
-
-impl<'self> Iterator<&'self str> for StrSplitIterator<'self> {
- #[inline]
- fn next(&mut self) -> Option<&'self str> {
- if self.finished { return None; }
-
- match self.it.next() {
- Some((from, to)) => {
- let ret = Some(self.it.haystack.slice(self.last_end, from));
- self.last_end = to;
- ret
- }
- None => {
- self.finished = true;
- Some(self.it.haystack.slice(self.last_end, self.it.haystack.len()))
- }
- }
- }
-}
-
-// Helper functions used for Unicode normalization
-fn canonical_sort(comb: &mut [(char, u8)]) {
- use iter::range;
- use tuple::CopyableTuple;
-
- let len = comb.len();
- for i in range(0, len) {
- let mut swapped = false;
- for j in range(1, len-i) {
- let classA = comb[j-1].second();
- let classB = comb[j].second();
- if classA != 0 && classB != 0 && classA > classB {
- comb.swap(j-1, j);
- swapped = true;
- }
- }
- if !swapped { break; }
- }
-}
-
-#[deriving(Clone)]
-enum NormalizationForm {
- NFD,
- NFKD
-}
-
-/// External iterator for a string's normalization's characters.
-/// Use with the `std::iter` module.
-#[deriving(Clone)]
-struct NormalizationIterator<'self> {
- priv kind: NormalizationForm,
- priv iter: CharIterator<'self>,
- priv buffer: ~[(char, u8)],
- priv sorted: bool
-}
-
-impl<'self> Iterator<char> for NormalizationIterator<'self> {
- #[inline]
- fn next(&mut self) -> Option<char> {
- use unicode::decompose::canonical_combining_class;
-
- match self.buffer.head_opt() {
- Some(&(c, 0)) => {
- self.sorted = false;
- self.buffer.shift();
- return Some(c);
- }
- Some(&(c, _)) if self.sorted => {
- self.buffer.shift();
- return Some(c);
- }
- _ => self.sorted = false
- }
-
- let decomposer = match self.kind {
- NFD => char::decompose_canonical,
- NFKD => char::decompose_compatible
- };
-
- if !self.sorted {
- for ch in self.iter {
- decomposer(ch, |d| {
- let class = canonical_combining_class(d);
- if class == 0 && !self.sorted {
- canonical_sort(self.buffer);
- self.sorted = true;
- }
- self.buffer.push((d, class));
- });
- if self.sorted { break }
- }
- }
-
- if !self.sorted {
- canonical_sort(self.buffer);
- self.sorted = true;
- }
-
- match self.buffer.shift_opt() {
- Some((c, 0)) => {
- self.sorted = false;
- Some(c)
- }
- Some((c, _)) => Some(c),
- None => None
- }
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- let (lower, _) = self.iter.size_hint();
- (lower, None)
- }
-}
-
-/// Replace all occurrences of one string with another
-///
-/// # Arguments
-///
-/// * s - The string containing substrings to replace
-/// * from - The string to replace
-/// * to - The replacement string
-///
-/// # Return value
-///
-/// The original string with all occurances of `from` replaced with `to`
-pub fn replace(s: &str, from: &str, to: &str) -> ~str {
- let mut result = ~"";
- let mut last_end = 0;
- for (start, end) in s.match_indices(from) {
- result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
- result.push_str(to);
- last_end = end;
- }
- result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
- result
-}
-
-/*
-Section: Comparing strings
-*/
-
-/// Bytewise slice equality
-#[cfg(not(test))]
-#[lang="str_eq"]
-#[inline]
-pub fn eq_slice(a: &str, b: &str) -> bool {
- a.as_imm_buf(|ap, alen| {
- b.as_imm_buf(|bp, blen| {
- if (alen != blen) { false }
- else {
- unsafe {
- libc::memcmp(ap as *libc::c_void,
- bp as *libc::c_void,
- alen as libc::size_t) == 0
- }
- }
- })
- })
-}
-
-/// Bytewise slice equality
-#[cfg(test)]
-#[inline]
-pub fn eq_slice(a: &str, b: &str) -> bool {
- a.as_imm_buf(|ap, alen| {
- b.as_imm_buf(|bp, blen| {
- if (alen != blen) { false }
- else {
- unsafe {
- libc::memcmp(ap as *libc::c_void,
- bp as *libc::c_void,
- alen as libc::size_t) == 0
- }
- }
- })
- })
-}
-
-/// Bytewise string equality
-#[cfg(not(test))]
-#[lang="uniq_str_eq"]
-#[inline]
-pub fn eq(a: &~str, b: &~str) -> bool {
- eq_slice(*a, *b)
-}
-
-#[cfg(test)]
-#[inline]
-pub fn eq(a: &~str, b: &~str) -> bool {
- eq_slice(*a, *b)
-}
-
-/*
-Section: Misc
-*/
-
-/// Determines if a vector of bytes contains valid UTF-8
-pub fn is_utf8(v: &[u8]) -> bool {
- let mut i = 0u;
- let total = v.len();
- fn unsafe_get(xs: &[u8], i: uint) -> u8 {
- unsafe { *xs.unsafe_ref(i) }
- }
- while i < total {
- let v_i = unsafe_get(v, i);
- if v_i < 128u8 {
- i += 1u;
- } else {
- let w = utf8_char_width(v_i);
- if w == 0u { return false; }
-
- let nexti = i + w;
- if nexti > total { return false; }
-
- // 2-byte encoding is for codepoints \u0080 to \u07ff
- // first C2 80 last DF BF
- // 3-byte encoding is for codepoints \u0800 to \uffff
- // first E0 A0 80 last EF BF BF
- // excluding surrogates codepoints \ud800 to \udfff
- // ED A0 80 to ED BF BF
- // 4-byte encoding is for codepoints \u10000 to \u10ffff
- // first F0 90 80 80 last F4 8F BF BF
- //
- // Use the UTF-8 syntax from the RFC
- //
- // https://tools.ietf.org/html/rfc3629
- // UTF8-1 = %x00-7F
- // UTF8-2 = %xC2-DF UTF8-tail
- // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
- // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
- // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
- // %xF4 %x80-8F 2( UTF8-tail )
- // UTF8-tail = %x80-BF
- match w {
- 2 => if unsafe_get(v, i + 1) & 192u8 != TAG_CONT_U8 {
- return false
- },
- 3 => match (v_i,
- unsafe_get(v, i + 1),
- unsafe_get(v, i + 2) & 192u8) {
- (0xE0 , 0xA0 .. 0xBF, TAG_CONT_U8) => (),
- (0xE1 .. 0xEC, 0x80 .. 0xBF, TAG_CONT_U8) => (),
- (0xED , 0x80 .. 0x9F, TAG_CONT_U8) => (),
- (0xEE .. 0xEF, 0x80 .. 0xBF, TAG_CONT_U8) => (),
- _ => return false,
- },
- _ => match (v_i,
- unsafe_get(v, i + 1),
- unsafe_get(v, i + 2) & 192u8,
- unsafe_get(v, i + 3) & 192u8) {
- (0xF0 , 0x90 .. 0xBF, TAG_CONT_U8, TAG_CONT_U8) => (),
- (0xF1 .. 0xF3, 0x80 .. 0xBF, TAG_CONT_U8, TAG_CONT_U8) => (),
- (0xF4 , 0x80 .. 0x8F, TAG_CONT_U8, TAG_CONT_U8) => (),
- _ => return false,
- },
- }
-
- i = nexti;
- }
- }
- true
-}
-
-/// Determines if a vector of `u16` contains valid UTF-16
-pub fn is_utf16(v: &[u16]) -> bool {
- let len = v.len();
- let mut i = 0u;
- while (i < len) {
- let u = v[i];
-
- if u <= 0xD7FF_u16 || u >= 0xE000_u16 {
- i += 1u;
-
- } else {
- if i+1u < len { return false; }
- let u2 = v[i+1u];
- if u < 0xD7FF_u16 || u > 0xDBFF_u16 { return false; }
- if u2 < 0xDC00_u16 || u2 > 0xDFFF_u16 { return false; }
- i += 2u;
- }
- }
- return true;
-}
-
-/// Iterates over the utf-16 characters in the specified slice, yielding each
-/// decoded unicode character to the function provided.
-///
-/// # Failures
-///
-/// * Fails on invalid utf-16 data
-pub fn utf16_chars(v: &[u16], f: |char|) {
- let len = v.len();
- let mut i = 0u;
- while (i < len && v[i] != 0u16) {
- let u = v[i];
-
- if u <= 0xD7FF_u16 || u >= 0xE000_u16 {
- f(unsafe { cast::transmute(u as u32) });
- i += 1u;
-
- } else {
- let u2 = v[i+1u];
- assert!(u >= 0xD800_u16 && u <= 0xDBFF_u16);
- assert!(u2 >= 0xDC00_u16 && u2 <= 0xDFFF_u16);
- let mut c: u32 = (u - 0xD800_u16) as u32;
- c = c << 10;
- c |= (u2 - 0xDC00_u16) as u32;
- c |= 0x1_0000_u32 as u32;
- f(unsafe { cast::transmute(c) });
- i += 2u;
- }
- }
-}
-
-/// Allocates a new string from the utf-16 slice provided
-pub fn from_utf16(v: &[u16]) -> ~str {
- let mut buf = ~"";
- buf.reserve(v.len());
- utf16_chars(v, |ch| buf.push_char(ch));
- buf
-}
-
-/// Allocates a new string with the specified capacity. The string returned is
-/// the empty string, but has capacity for much more.
-#[inline]
-pub fn with_capacity(capacity: uint) -> ~str {
- unsafe {
- cast::transmute(vec::with_capacity::<~[u8]>(capacity))
- }
-}
-
-// https://tools.ietf.org/html/rfc3629
-static UTF8_CHAR_WIDTH: [u8, ..256] = [
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
-0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
-4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
-];
-
-/// Given a first byte, determine how many bytes are in this UTF-8 character
-pub fn utf8_char_width(b: u8) -> uint {
- return UTF8_CHAR_WIDTH[b] as uint;
-}
-
-/// Struct that contains a `char` and
-/// the index of the first byte of the next `char` in a string.
-/// This is being used as a datastructure for iterating over
-/// the utf8 bytes of a string.
-pub struct CharRange {
- /// Current `char`
- ch: char,
- /// Index of the first byte of the next `char`
- next: uint
-}
-
-// Return the initial codepoint accumulator for the first byte.
-// The first byte is special, only want bottom 5 bits for width 2, 4 bits
-// for width 3, and 3 bits for width 4
-macro_rules! utf8_first_byte(
- ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as uint)
-)
-
-// return the value of $ch updated with continuation byte $byte
-macro_rules! utf8_acc_cont_byte(
- ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as uint)
-)
-
-static TAG_CONT_U8: u8 = 128u8;
-
-/// Unsafe operations
-pub mod raw {
- use cast;
- use libc;
- use ptr;
- use str::is_utf8;
- use vec;
- use vec::MutableVector;
- use unstable::raw::Slice;
-
- /// Create a Rust string from a *u8 buffer of the given length
- pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
- let mut v: ~[u8] = vec::with_capacity(len);
- v.as_mut_buf(|vbuf, _len| ptr::copy_memory(vbuf, buf as *u8, len));
- vec::raw::set_len(&mut v, len);
-
- assert!(is_utf8(v));
- ::cast::transmute(v)
- }
-
- #[lang="strdup_uniq"]
- #[cfg(not(test))]
- #[allow(missing_doc)]
- #[inline]
- pub unsafe fn strdup_uniq(ptr: *u8, len: uint) -> ~str {
- from_buf_len(ptr, len)
- }
-
- /// Create a Rust string from a null-terminated C string
- pub unsafe fn from_c_str(buf: *libc::c_char) -> ~str {
- let mut curr = buf;
- let mut i = 0;
- while *curr != 0 {
- i += 1;
- curr = ptr::offset(buf, i);
- }
- from_buf_len(buf as *u8, i as uint)
- }
-
- /// Converts a vector of bytes to a new owned string.
- pub unsafe fn from_utf8(v: &[u8]) -> ~str {
- v.as_imm_buf(|buf, len| from_buf_len(buf, len))
- }
-
- /// Converts an owned vector of bytes to a new owned string. This assumes
- /// that the utf-8-ness of the vector has already been validated
- #[inline]
- pub unsafe fn from_utf8_owned(v: ~[u8]) -> ~str {
- cast::transmute(v)
- }
-
- /// Converts a byte to a string.
- pub unsafe fn from_byte(u: u8) -> ~str { from_utf8([u]) }
-
- /// Form a slice from a C string. Unsafe because the caller must ensure the
- /// C string has the static lifetime, or else the return value may be
- /// invalidated later.
- pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
- let s = s as *u8;
- let mut curr = s;
- let mut len = 0u;
- while *curr != 0u8 {
- len += 1u;
- curr = ptr::offset(s, len as int);
- }
- let v = Slice { data: s, len: len };
- assert!(is_utf8(::cast::transmute(v)));
- ::cast::transmute(v)
- }
-
- /// Takes a bytewise (not UTF-8) slice from a string.
- ///
- /// Returns the substring from [`begin`..`end`).
- ///
- /// # Failure
- ///
- /// If begin is greater than end.
- /// If end is greater than the length of the string.
- #[inline]
- pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
- assert!(begin <= end);
- assert!(end <= s.len());
- slice_unchecked(s, begin, end)
- }
-
- /// Takes a bytewise (not UTF-8) slice from a string.
- ///
- /// Returns the substring from [`begin`..`end`).
- ///
- /// Caller must check slice boundaries!
- #[inline]
- pub unsafe fn slice_unchecked<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
- s.as_imm_buf(|sbuf, _n| {
- cast::transmute(Slice {
- data: sbuf.offset(begin as int),
- len: end - begin,
- })
- })
- }
-
- /// Appends a byte to a string.
- /// The caller must preserve the valid UTF-8 property.
- #[inline]
- pub unsafe fn push_byte(s: &mut ~str, b: u8) {
- as_owned_vec(s).push(b)
- }
-
- /// Appends a vector of bytes to a string.
- /// The caller must preserve the valid UTF-8 property.
- #[inline]
- pub unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
- vec::bytes::push_bytes(as_owned_vec(s), bytes);
- }
-
- /// Removes the last byte from a string and returns it.
- /// The caller must preserve the valid UTF-8 property.
- pub unsafe fn pop_byte(s: &mut ~str) -> u8 {
- let len = s.len();
- assert!((len > 0u));
- let b = s[len - 1u];
- set_len(s, len - 1u);
- return b;
- }
-
- /// Removes the first byte from a string and returns it.
- /// The caller must preserve the valid UTF-8 property.
- pub unsafe fn shift_byte(s: &mut ~str) -> u8 {
- let len = s.len();
- assert!((len > 0u));
- let b = s[0];
- *s = s.slice(1, len).to_owned();
- return b;
- }
-
- /// Access the str in its vector representation.
- /// The caller must preserve the valid UTF-8 property when modifying.
- #[inline]
- pub unsafe fn as_owned_vec<'a>(s: &'a mut ~str) -> &'a mut ~[u8] {
- cast::transmute(s)
- }
-
- /// Sets the length of a string
- ///
- /// This will explicitly set the size of the string, without actually
- /// modifying its buffers, so it is up to the caller to ensure that
- /// the string is actually the specified size.
- #[inline]
- pub unsafe fn set_len(s: &mut ~str, new_len: uint) {
- vec::raw::set_len(as_owned_vec(s), new_len)
- }
-
- /// Sets the length of a string
- ///
- /// This will explicitly set the size of the string, without actually
- /// modifing its buffers, so it is up to the caller to ensure that
- /// the string is actually the specified size.
- #[test]
- fn test_from_buf_len() {
- unsafe {
- let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
- let b = vec::raw::to_ptr(a);
- let c = from_buf_len(b, 3u);
- assert_eq!(c, ~"AAA");
- }
- }
-}
-
-/*
-Section: Trait implementations
-*/
-
-#[cfg(not(test))]
-#[allow(missing_doc)]
-pub mod traits {
- use ops::Add;
- use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq};
- use super::{Str, eq_slice};
- use option::{Some, None};
-
- impl<'self> Add<&'self str,~str> for &'self str {
- #[inline]
- fn add(&self, rhs: & &'self str) -> ~str {
- let mut ret = self.to_owned();
- ret.push_str(*rhs);
- ret
- }
- }
-
- impl<'self> TotalOrd for &'self str {
- #[inline]
- fn cmp(&self, other: & &'self str) -> Ordering {
- for (s_b, o_b) in self.bytes().zip(other.bytes()) {
- match s_b.cmp(&o_b) {
- Greater => return Greater,
- Less => return Less,
- Equal => ()
- }
- }
-
- self.len().cmp(&other.len())
- }
- }
-
- impl TotalOrd for ~str {
- #[inline]
- fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
- }
-
- impl TotalOrd for @str {
- #[inline]
- fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
- }
-
- impl<'self> Eq for &'self str {
- #[inline]
- fn eq(&self, other: & &'self str) -> bool {
- eq_slice((*self), (*other))
- }
- #[inline]
- fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
- }
-
- impl Eq for ~str {
- #[inline]
- fn eq(&self, other: &~str) -> bool {
- eq_slice((*self), (*other))
- }
- }
-
- impl Eq for @str {
- #[inline]
- fn eq(&self, other: &@str) -> bool {
- eq_slice((*self), (*other))
- }
- }
-
- impl<'self> TotalEq for &'self str {
- #[inline]
- fn equals(&self, other: & &'self str) -> bool {
- eq_slice((*self), (*other))
- }
- }
-
- impl TotalEq for ~str {
- #[inline]
- fn equals(&self, other: &~str) -> bool {
- eq_slice((*self), (*other))
- }
- }
-
- impl TotalEq for @str {
- #[inline]
- fn equals(&self, other: &@str) -> bool {
- eq_slice((*self), (*other))
- }
- }
-
- impl<'self> Ord for &'self str {
- #[inline]
- fn lt(&self, other: & &'self str) -> bool { self.cmp(other) == Less }
- }
-
- impl Ord for ~str {
- #[inline]
- fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less }
- }
-
- impl Ord for @str {
- #[inline]
- fn lt(&self, other: &@str) -> bool { self.cmp(other) == Less }
- }
-
- impl<'self, S: Str> Equiv<S> for &'self str {
- #[inline]
- fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
- }
-
- impl<'self, S: Str> Equiv<S> for @str {
- #[inline]
- fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
- }
-
- impl<'self, S: Str> Equiv<S> for ~str {
- #[inline]
- fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
- }
-}
-
-#[cfg(test)]
-pub mod traits {}
-
-/// Any string that can be represented as a slice
-pub trait Str {
- /// Work with `self` as a slice.
- fn as_slice<'a>(&'a self) -> &'a str;
-
- /// Convert `self` into a ~str, not making a copy if possible
- fn into_owned(self) -> ~str;
-}
-
-impl<'self> Str for &'self str {
- #[inline]
- fn as_slice<'a>(&'a self) -> &'a str { *self }
-
- #[inline]
- fn into_owned(self) -> ~str { self.to_owned() }
-}
-
-impl<'self> Str for ~str {
- #[inline]
- fn as_slice<'a>(&'a self) -> &'a str {
- let s: &'a str = *self; s
- }
-
- #[inline]
- fn into_owned(self) -> ~str { self }
-}
-
-impl<'self> Str for @str {
- #[inline]
- fn as_slice<'a>(&'a self) -> &'a str {
- let s: &'a str = *self; s
- }
-
- #[inline]
- fn into_owned(self) -> ~str { self.to_owned() }
-}
-
-impl<'self> Container for &'self str {
- #[inline]
- fn len(&self) -> uint {
- self.as_imm_buf(|_p, n| n)
- }
-}
-
-impl Container for ~str {
- #[inline]
- fn len(&self) -> uint { self.as_slice().len() }
-}
-
-impl Container for @str {
- #[inline]
- fn len(&self) -> uint { self.as_slice().len() }
-}
-
-impl Mutable for ~str {
- /// Remove all content, make the string empty
- #[inline]
- fn clear(&mut self) {
- unsafe {
- raw::set_len(self, 0)
- }
- }
-}
-
-/// Methods for string slices
-pub trait StrSlice<'self> {
- /// Returns true if one string contains another
- ///
- /// # Arguments
- ///
- /// - needle - The string to look for
- fn contains<'a>(&self, needle: &'a str) -> bool;
-
- /// Returns true if a string contains a char.
- ///
- /// # Arguments
- ///
- /// - needle - The char to look for
- fn contains_char(&self, needle: char) -> bool;
-
- /// An iterator over the characters of `self`. Note, this iterates
- /// over unicode code-points, not unicode graphemes.
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: ~[char] = "abc åäö".chars().collect();
- /// assert_eq!(v, ~['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
- /// ```
- fn chars(&self) -> CharIterator<'self>;
-
- /// An iterator over the characters of `self`, in reverse order.
- fn chars_rev(&self) -> CharRevIterator<'self>;
-
- /// An iterator over the bytes of `self`
- fn bytes(&self) -> ByteIterator<'self>;
-
- /// An iterator over the bytes of `self`, in reverse order
- fn bytes_rev(&self) -> ByteRevIterator<'self>;
-
- /// An iterator over the characters of `self` and their byte offsets.
- fn char_indices(&self) -> CharOffsetIterator<'self>;
-
- /// An iterator over the characters of `self` and their byte offsets,
- /// in reverse order.
- fn char_indices_rev(&self) -> CharOffsetRevIterator<'self>;
-
- /// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`.
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: ~[&str] = "Mary had a little lamb".split(' ').collect();
- /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
- ///
- /// let v: ~[&str] = "abc1def2ghi".split(|c: char| c.is_digit()).collect();
- /// assert_eq!(v, ~["abc", "def", "ghi"]);
- /// ```
- fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplitIterator<'self, Sep>;
-
- /// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`, restricted to splitting at most `count`
- /// times.
- fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitNIterator<'self, Sep>;
-
- /// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`.
- ///
- /// Equivalent to `split`, except that the trailing substring
- /// is skipped if empty (terminator semantics).
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: ~[&str] = "A.B.".split_terminator('.').collect();
- /// assert_eq!(v, ~["A", "B"]);
- /// ```
- fn split_terminator<Sep: CharEq>(&self, sep: Sep) -> CharSplitIterator<'self, Sep>;
-
- /// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`, in reverse order
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: ~[&str] = "Mary had a little lamb".rsplit(' ').collect();
- /// assert_eq!(v, ~["lamb", "little", "a", "had", "Mary"]);
- /// ```
- fn rsplit<Sep: CharEq>(&self, sep: Sep) -> CharRSplitIterator<'self, Sep>;
-
- /// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`, starting from the end of the string.
- /// Restricted to splitting at most `count` times.
- fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitNIterator<'self, Sep>;
-
- /// An iterator over the start and end indices of each match of
- /// `sep` within `self`.
- fn match_indices(&self, sep: &'self str) -> MatchesIndexIterator<'self>;
-
- /// An iterator over the substrings of `self` separated by `sep`.
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: ~[&str] = "abcXXXabcYYYabc".split_str("abc").collect()
- /// assert_eq!(v, ["", "XXX", "YYY", ""]);
- /// ```
- fn split_str(&self, &'self str) -> StrSplitIterator<'self>;
-
- /// An iterator over the lines of a string (subsequences separated
- /// by `\n`).
- fn lines(&self) -> CharSplitIterator<'self, char>;
-
- /// An iterator over the lines of a string, separated by either
- /// `\n` or (`\r\n`).
- fn lines_any(&self) -> AnyLineIterator<'self>;
-
- /// An iterator over the words of a string (subsequences separated
- /// by any sequence of whitespace).
- fn words(&self) -> WordIterator<'self>;
-
- /// An Iterator over the string in Unicode Normalization Form D (canonical decomposition)
- fn nfd_chars(&self) -> NormalizationIterator<'self>;
-
- /// An Iterator over the string in Unicode Normalization Form KD (compatibility decomposition)
- fn nfkd_chars(&self) -> NormalizationIterator<'self>;
-
- /// Returns true if the string contains only whitespace
- ///
- /// Whitespace characters are determined by `char::is_whitespace`
- fn is_whitespace(&self) -> bool;
-
- /// Returns true if the string contains only alphanumerics
- ///
- /// Alphanumeric characters are determined by `char::is_alphanumeric`
- fn is_alphanumeric(&self) -> bool;
-
- /// Returns the number of characters that a string holds
- fn char_len(&self) -> uint;
-
- /// Returns a slice of the given string from the byte range
- /// [`begin`..`end`)
- ///
- /// Fails when `begin` and `end` do not point to valid characters or
- /// beyond the last character of the string
- fn slice(&self, begin: uint, end: uint) -> &'self str;
-
- /// Returns a slice of the string from `begin` to its end.
- ///
- /// Fails when `begin` does not point to a valid character, or is
- /// out of bounds.
- fn slice_from(&self, begin: uint) -> &'self str;
-
- /// Returns a slice of the string from the beginning to byte
- /// `end`.
- ///
- /// Fails when `end` does not point to a valid character, or is
- /// out of bounds.
- fn slice_to(&self, end: uint) -> &'self str;
-
- /// Returns a slice of the string from the char range
- /// [`begin`..`end`).
- ///
- /// Fails if `begin` > `end` or the either `begin` or `end` are
- /// beyond the last character of the string.
- fn slice_chars(&self, begin: uint, end: uint) -> &'self str;
-
- /// Returns true if `needle` is a prefix of the string.
- fn starts_with(&self, needle: &str) -> bool;
-
- /// Returns true if `needle` is a suffix of the string.
- fn ends_with(&self, needle: &str) -> bool;
-
- /// Escape each char in `s` with char::escape_default.
- fn escape_default(&self) -> ~str;
-
- /// Escape each char in `s` with char::escape_unicode.
- fn escape_unicode(&self) -> ~str;
-
- /// Returns a string with leading and trailing whitespace removed
- fn trim(&self) -> &'self str;
-
- /// Returns a string with leading whitespace removed
- fn trim_left(&self) -> &'self str;
-
- /// Returns a string with trailing whitespace removed
- fn trim_right(&self) -> &'self str;
-
- /// Returns a string with characters that match `to_trim` removed.
- ///
- /// # Arguments
- ///
- /// * to_trim - a character matcher
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
- /// assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
- /// assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
- /// ```
- fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
-
- /// Returns a string with leading `chars_to_trim` removed.
- ///
- /// # Arguments
- ///
- /// * to_trim - a character matcher
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
- /// assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
- /// assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
- /// ```
- fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
-
- /// Returns a string with trailing `chars_to_trim` removed.
- ///
- /// # Arguments
- ///
- /// * to_trim - a character matcher
- ///
- /// # Example
- ///
- /// ```rust
- /// assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
- /// assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
- /// assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
- /// ```
- fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
-
- /// Replace all occurrences of one string with another
- ///
- /// # Arguments
- ///
- /// * from - The string to replace
- /// * to - The replacement string
- ///
- /// # Return value
- ///
- /// The original string with all occurances of `from` replaced with `to`
- fn replace(&self, from: &str, to: &str) -> ~str;
-
- /// Copy a slice into a new owned str
- fn to_owned(&self) -> ~str;
-
- /// Copy a slice into a new managed str
- fn to_managed(&self) -> @str;
-
- /// Converts to a vector of `u16` encoded as UTF-16.
- fn to_utf16(&self) -> ~[u16];
-
- /// Copy a slice into a new `SendStr`
- fn to_send_str(&self) -> SendStr;
-
- /// Returns false if the index points into the middle of a multi-byte
- /// character sequence.
- fn is_char_boundary(&self, index: uint) -> bool;
-
- /// Pluck a character out of a string and return the index of the next
- /// character.
- ///
- /// This function can be used to iterate over the unicode characters of a
- /// string.
- ///
- /// # Example
- ///
- /// ```rust
- /// let s = "中华Việt Nam";
- /// let i = 0u;
- /// while i < s.len() {
- /// let CharRange {ch, next} = s.char_range_at(i);
- /// println!("{}: {}", i, ch);
- /// i = next;
- /// }
- /// ```
- ///
- /// # Example output
- ///
- /// ```
- /// 0: 中
- /// 3: 华
- /// 6: V
- /// 7: i
- /// 8: ệ
- /// 11: t
- /// 12:
- /// 13: N
- /// 14: a
- /// 15: m
- /// ```
- ///
- /// # Arguments
- ///
- /// * s - The string
- /// * i - The byte offset of the char to extract
- ///
- /// # Return value
- ///
- /// A record {ch: char, next: uint} containing the char value and the byte
- /// index of the next unicode character.
- ///
- /// # Failure
- ///
- /// If `i` is greater than or equal to the length of the string.
- /// If `i` is not the index of the beginning of a valid UTF-8 character.
- fn char_range_at(&self, start: uint) -> CharRange;
-
- /// Given a byte position and a str, return the previous char and its position.
- ///
- /// This function can be used to iterate over a unicode string in reverse.
- ///
- /// Returns 0 for next index if called on start index 0.
- fn char_range_at_reverse(&self, start: uint) -> CharRange;
-
- /// Plucks the character starting at the `i`th byte of a string
- fn char_at(&self, i: uint) -> char;
-
- /// Plucks the character ending at the `i`th byte of a string
- fn char_at_reverse(&self, i: uint) -> char;
-
- /// Work with the byte buffer of a string as a byte slice.
- fn as_bytes(&self) -> &'self [u8];
-
- /// Returns the byte index of the first character of `self` that matches `search`
- ///
- /// # Return value
- ///
- /// `Some` containing the byte index of the last matching character
- /// or `None` if there is no match
- fn find<C: CharEq>(&self, search: C) -> Option<uint>;
-
- /// Returns the byte index of the last character of `self` that matches `search`
- ///
- /// # Return value
- ///
- /// `Some` containing the byte index of the last matching character
- /// or `None` if there is no match
- fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
-
- /// Returns the byte index of the first matching substring
- ///
- /// # Arguments
- ///
- /// * `needle` - The string to search for
- ///
- /// # Return value
- ///
- /// `Some` containing the byte index of the first matching substring
- /// or `None` if there is no match
- fn find_str(&self, &str) -> Option<uint>;
-
- /// Given a string, make a new string with repeated copies of it.
- fn repeat(&self, nn: uint) -> ~str;
-
- /// Retrieves the first character from a string slice and returns
- /// it. This does not allocate a new string; instead, it returns a
- /// slice that point one character beyond the character that was
- /// shifted.
- ///
- /// # Failure
- ///
- /// If the string does not contain any characters
- fn slice_shift_char(&self) -> (char, &'self str);
-
- /// Levenshtein Distance between two strings.
- fn lev_distance(&self, t: &str) -> uint;
-
- /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
- ///
- /// Fails if `inner` is not a direct slice contained within self.
- ///
- /// # Example
- ///
- /// ```rust
- /// let string = "a\nb\nc";
- /// let mut lines = ~[];
- /// for line in string.lines() { lines.push(line) }
- ///
- /// assert!(string.subslice_offset(lines[0]) == 0); // &"a"
- /// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
- /// assert!(string.subslice_offset(lines[2]) == 4); // &"c"
- /// ```
- fn subslice_offset(&self, inner: &str) -> uint;
-
- /// Work with the byte buffer and length of a slice.
- ///
- /// The buffer does not have a null terminator.
- fn as_imm_buf<T>(&self, f: |*u8, uint| -> T) -> T;
-}
-
-impl<'self> StrSlice<'self> for &'self str {
- #[inline]
- fn contains<'a>(&self, needle: &'a str) -> bool {
- self.find_str(needle).is_some()
- }
-
- #[inline]
- fn contains_char(&self, needle: char) -> bool {
- self.find(needle).is_some()
- }
-
- #[inline]
- fn chars(&self) -> CharIterator<'self> {
- CharIterator{string: *self}
- }
-
- #[inline]
- fn chars_rev(&self) -> CharRevIterator<'self> {
- self.chars().invert()
- }
-
- #[inline]
- fn bytes(&self) -> ByteIterator<'self> {
- self.as_bytes().iter().map(|&b| b)
- }
-
- #[inline]
- fn bytes_rev(&self) -> ByteRevIterator<'self> {
- self.bytes().invert()
- }
-
- #[inline]
- fn char_indices(&self) -> CharOffsetIterator<'self> {
- CharOffsetIterator{string: *self, iter: self.chars()}
- }
-
- #[inline]
- fn char_indices_rev(&self) -> CharOffsetRevIterator<'self> {
- self.char_indices().invert()
- }
-
- #[inline]
- fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplitIterator<'self, Sep> {
- CharSplitIterator {
- string: *self,
- only_ascii: sep.only_ascii(),
- sep: sep,
- allow_trailing_empty: true,
- finished: false,
- }
- }
-
- #[inline]
- fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint)
- -> CharSplitNIterator<'self, Sep> {
- CharSplitNIterator {
- iter: self.split(sep),
- count: count,
- invert: false,
- }
- }
-
- #[inline]
- fn split_terminator<Sep: CharEq>(&self, sep: Sep)
- -> CharSplitIterator<'self, Sep> {
- CharSplitIterator {
- allow_trailing_empty: false,
- ..self.split(sep)
- }
- }
-
- #[inline]
- fn rsplit<Sep: CharEq>(&self, sep: Sep) -> CharRSplitIterator<'self, Sep> {
- self.split(sep).invert()
- }
-
- #[inline]
- fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint)
- -> CharSplitNIterator<'self, Sep> {
- CharSplitNIterator {
- iter: self.split(sep),
- count: count,
- invert: true,
- }
- }
-
- #[inline]
- fn match_indices(&self, sep: &'self str) -> MatchesIndexIterator<'self> {
- assert!(!sep.is_empty())
- MatchesIndexIterator {
- haystack: *self,
- needle: sep,
- position: 0
- }
- }
-
- #[inline]
- fn split_str(&self, sep: &'self str) -> StrSplitIterator<'self> {
- StrSplitIterator {
- it: self.match_indices(sep),
- last_end: 0,
- finished: false
- }
- }
-
- #[inline]
- fn lines(&self) -> CharSplitIterator<'self, char> {
- self.split_terminator('\n')
- }
-
- fn lines_any(&self) -> AnyLineIterator<'self> {
- self.lines().map(|line| {
- let l = line.len();
- if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
- else { line }
- })
- }
-
- #[inline]
- fn words(&self) -> WordIterator<'self> {
- self.split(char::is_whitespace).filter(|s| !s.is_empty())
- }
-
- #[inline]
- fn nfd_chars(&self) -> NormalizationIterator<'self> {
- NormalizationIterator {
- iter: self.chars(),
- buffer: ~[],
- sorted: false,
- kind: NFD
- }
- }
-
- #[inline]
- fn nfkd_chars(&self) -> NormalizationIterator<'self> {
- NormalizationIterator {
- iter: self.chars(),
- buffer: ~[],
- sorted: false,
- kind: NFKD
- }
- }
-
- #[inline]
- fn is_whitespace(&self) -> bool { self.chars().all(char::is_whitespace) }
-
- #[inline]
- fn is_alphanumeric(&self) -> bool { self.chars().all(char::is_alphanumeric) }
-
- #[inline]
- fn char_len(&self) -> uint { self.chars().len() }
-
- #[inline]
- fn slice(&self, begin: uint, end: uint) -> &'self str {
- assert!(self.is_char_boundary(begin) && self.is_char_boundary(end));
- unsafe { raw::slice_bytes(*self, begin, end) }
- }
-
- #[inline]
- fn slice_from(&self, begin: uint) -> &'self str {
- self.slice(begin, self.len())
- }
-
- #[inline]
- fn slice_to(&self, end: uint) -> &'self str {
- assert!(self.is_char_boundary(end));
- unsafe { raw::slice_bytes(*self, 0, end) }
- }
-
- fn slice_chars(&self, begin: uint, end: uint) -> &'self str {
- assert!(begin <= end);
- let mut count = 0;
- let mut begin_byte = None;
- let mut end_byte = None;
-
- // This could be even more efficient by not decoding,
- // only finding the char boundaries
- for (idx, _) in self.char_indices() {
- if count == begin { begin_byte = Some(idx); }
- if count == end { end_byte = Some(idx); break; }
- count += 1;
- }
- if begin_byte.is_none() && count == begin { begin_byte = Some(self.len()) }
- if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
-
- match (begin_byte, end_byte) {
- (None, _) => fail!("slice_chars: `begin` is beyond end of string"),
- (_, None) => fail!("slice_chars: `end` is beyond end of string"),
- (Some(a), Some(b)) => unsafe { raw::slice_bytes(*self, a, b) }
- }
- }
-
- #[inline]
- fn starts_with<'a>(&self, needle: &'a str) -> bool {
- let n = needle.len();
- self.len() >= n && needle.as_bytes() == self.as_bytes().slice_to(n)
- }
-
- #[inline]
- fn ends_with(&self, needle: &str) -> bool {
- let (m, n) = (self.len(), needle.len());
- m >= n && needle.as_bytes() == self.as_bytes().slice_from(m - n)
- }
-
- fn escape_default(&self) -> ~str {
- let mut out: ~str = ~"";
- out.reserve_at_least(self.len());
- for c in self.chars() {
- c.escape_default(|c| out.push_char(c));
- }
- out
- }
-
- fn escape_unicode(&self) -> ~str {
- let mut out: ~str = ~"";
- out.reserve_at_least(self.len());
- for c in self.chars() {
- c.escape_unicode(|c| out.push_char(c));
- }
- out
- }
-
- #[inline]
- fn trim(&self) -> &'self str {
- self.trim_left().trim_right()
- }
-
- #[inline]
- fn trim_left(&self) -> &'self str {
- self.trim_left_chars(&char::is_whitespace)
- }
-
- #[inline]
- fn trim_right(&self) -> &'self str {
- self.trim_right_chars(&char::is_whitespace)
- }
-
- #[inline]
- fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
- self.trim_left_chars(to_trim).trim_right_chars(to_trim)
- }
-
- #[inline]
- fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
- match self.find(|c: char| !to_trim.matches(c)) {
- None => "",
- Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
- }
- }
-
- #[inline]
- fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
- match self.rfind(|c: char| !to_trim.matches(c)) {
- None => "",
- Some(last) => {
- let next = self.char_range_at(last).next;
- unsafe { raw::slice_bytes(*self, 0u, next) }
- }
- }
- }
-
- fn replace(&self, from: &str, to: &str) -> ~str {
- let mut result = ~"";
- let mut last_end = 0;
- for (start, end) in self.match_indices(from) {
- result.push_str(unsafe{raw::slice_bytes(*self, last_end, start)});
- result.push_str(to);
- last_end = end;
- }
- result.push_str(unsafe{raw::slice_bytes(*self, last_end, self.len())});
- result
- }
-
- #[inline]
- fn to_owned(&self) -> ~str {
- self.as_imm_buf(|src, len| {
- unsafe {
- let mut v = vec::with_capacity(len);
-
- v.as_mut_buf(|dst, _| ptr::copy_memory(dst, src, len));
- vec::raw::set_len(&mut v, len);
- ::cast::transmute(v)
- }
- })
- }
-
- #[inline]
- fn to_managed(&self) -> @str {
- unsafe {
- let v: *&[u8] = cast::transmute(self);
- cast::transmute(at_vec::to_managed(*v))
- }
- }
-
- fn to_utf16(&self) -> ~[u16] {
- let mut u = ~[];
- for ch in self.chars() {
- // Arithmetic with u32 literals is easier on the eyes than chars.
- let mut ch = ch as u32;
-
- if (ch & 0xFFFF_u32) == ch {
- // The BMP falls through (assuming non-surrogate, as it
- // should)
- assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
- u.push(ch as u16)
- } else {
- // Supplementary planes break into surrogates.
- assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
- ch -= 0x1_0000_u32;
- let w1 = 0xD800_u16 | ((ch >> 10) as u16);
- let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
- u.push_all([w1, w2])
- }
- }
- u
- }
-
- #[inline]
- fn to_send_str(&self) -> SendStr {
- SendStrOwned(self.to_owned())
- }
-
- #[inline]
- fn is_char_boundary(&self, index: uint) -> bool {
- if index == self.len() { return true; }
- let b = self[index];
- return b < 128u8 || b >= 192u8;
- }
-
- #[inline]
- fn char_range_at(&self, i: uint) -> CharRange {
- if (self[i] < 128u8) {
- return CharRange {ch: self[i] as char, next: i + 1 };
- }
-
- // Multibyte case is a fn to allow char_range_at to inline cleanly
- fn multibyte_char_range_at(s: &str, i: uint) -> CharRange {
- let mut val = s[i] as uint;
- let w = UTF8_CHAR_WIDTH[val] as uint;
- assert!((w != 0));
-
- val = utf8_first_byte!(val, w);
- val = utf8_acc_cont_byte!(val, s[i + 1]);
- if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
- if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
-
- return CharRange {ch: unsafe { transmute(val as u32) }, next: i + w};
- }
-
- return multibyte_char_range_at(*self, i);
- }
-
- #[inline]
- fn char_at(&self, i: uint) -> char { self.char_range_at(i).ch }
-
- #[inline]
- fn char_range_at_reverse(&self, start: uint) -> CharRange {
- let mut prev = start;
-
- prev = prev.saturating_sub(1);
- if self[prev] < 128 { return CharRange{ch: self[prev] as char, next: prev} }
-
- // Multibyte case is a fn to allow char_range_at_reverse to inline cleanly
- fn multibyte_char_range_at_reverse(s: &str, mut i: uint) -> CharRange {
- // while there is a previous byte == 10......
- while i > 0 && s[i] & 192u8 == TAG_CONT_U8 {
- i -= 1u;
- }
-
- let mut val = s[i] as uint;
- let w = UTF8_CHAR_WIDTH[val] as uint;
- assert!((w != 0));
-
- val = utf8_first_byte!(val, w);
- val = utf8_acc_cont_byte!(val, s[i + 1]);
- if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
- if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
-
- return CharRange {ch: unsafe { transmute(val as u32) }, next: i};
- }
-
- return multibyte_char_range_at_reverse(*self, prev);
- }
-
- #[inline]
- fn char_at(&self, i: uint) -> char {
- self.char_range_at(i).ch
- }
-
- #[inline]
- fn char_at_reverse(&self, i: uint) -> char {
- self.char_range_at_reverse(i).ch
- }
-
- #[inline]
- fn as_bytes(&self) -> &'self [u8] {
- unsafe { cast::transmute(*self) }
- }
-
- fn find<C: CharEq>(&self, search: C) -> Option<uint> {
- if search.only_ascii() {
- self.bytes().position(|b| search.matches(b as char))
- } else {
- for (index, c) in self.char_indices() {
- if search.matches(c) { return Some(index); }
- }
- None
- }
- }
-
- fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
- if search.only_ascii() {
- self.bytes().rposition(|b| search.matches(b as char))
- } else {
- for (index, c) in self.char_indices_rev() {
- if search.matches(c) { return Some(index); }
- }
- None
- }
- }
-
- fn find_str(&self, needle: &str) -> Option<uint> {
- if needle.is_empty() {
- Some(0)
- } else {
- self.match_indices(needle)
- .next()
- .map(|(start, _end)| start)
- }
- }
-
- fn repeat(&self, nn: uint) -> ~str {
- let mut ret = with_capacity(nn * self.len());
- for _ in range(0, nn) {
- ret.push_str(*self);
- }
- ret
- }
-
- #[inline]
- fn slice_shift_char(&self) -> (char, &'self str) {
- let CharRange {ch, next} = self.char_range_at(0u);
- let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
- return (ch, next_s);
- }
-
- fn lev_distance(&self, t: &str) -> uint {
- let slen = self.len();
- let tlen = t.len();
-
- if slen == 0 { return tlen; }
- if tlen == 0 { return slen; }
-
- let mut dcol = vec::from_fn(tlen + 1, |x| x);
-
- for (i, sc) in self.chars().enumerate() {
-
- let mut current = i;
- dcol[0] = current + 1;
-
- for (j, tc) in t.chars().enumerate() {
-
- let next = dcol[j + 1];
-
- if sc == tc {
- dcol[j + 1] = current;
- } else {
- dcol[j + 1] = ::cmp::min(current, next);
- dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
- }
-
- current = next;
- }
- }
-
- return dcol[tlen];
- }
-
- fn subslice_offset(&self, inner: &str) -> uint {
- self.as_imm_buf(|a, a_len| {
- inner.as_imm_buf(|b, b_len| {
- let a_start: uint;
- let a_end: uint;
- let b_start: uint;
- let b_end: uint;
- unsafe {
- a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
- b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
- }
- assert!(a_start <= b_start);
- assert!(b_end <= a_end);
- b_start - a_start
- })
- })
- }
-
- #[inline]
- fn as_imm_buf<T>(&self, f: |*u8, uint| -> T) -> T {
- let v: &[u8] = unsafe { cast::transmute(*self) };
- v.as_imm_buf(f)
- }
-}
-
-/// Methods for owned strings
-pub trait OwnedStr {
- /// Appends a string slice to the back of a string, without overallocating
- fn push_str_no_overallocate(&mut self, rhs: &str);
-
- /// Appends a string slice to the back of a string
- fn push_str(&mut self, rhs: &str);
-
- /// Appends a character to the back of a string
- fn push_char(&mut self, c: char);
-
- /// Remove the final character from a string and return it
- ///
- /// # Failure
- ///
- /// If the string does not contain any characters
- fn pop_char(&mut self) -> char;
-
- /// Remove the first character from a string and return it
- ///
- /// # Failure
- ///
- /// If the string does not contain any characters
- fn shift_char(&mut self) -> char;
-
- /// Prepend a char to a string
- fn unshift_char(&mut self, ch: char);
-
- /// Concatenate two strings together.
- fn append(self, rhs: &str) -> ~str;
-
- /// Reserves capacity for exactly `n` bytes in the given string.
- ///
- /// Assuming single-byte characters, the resulting string will be large
- /// enough to hold a string of length `n`.
- ///
- /// If the capacity for `s` is already equal to or greater than the requested
- /// capacity, then no action is taken.
- ///
- /// # Arguments
- ///
- /// * s - A string
- /// * n - The number of bytes to reserve space for
- fn reserve(&mut self, n: uint);
-
- /// Reserves capacity for at least `n` bytes in the given string.
- ///
- /// Assuming single-byte characters, the resulting string will be large
- /// enough to hold a string of length `n`.
- ///
- /// This function will over-allocate in order to amortize the allocation costs
- /// in scenarios where the caller may need to repeatedly reserve additional
- /// space.
- ///
- /// If the capacity for `s` is already equal to or greater than the requested
- /// capacity, then no action is taken.
- ///
- /// # Arguments
- ///
- /// * s - A string
- /// * n - The number of bytes to reserve space for
- fn reserve_at_least(&mut self, n: uint);
-
- /// Returns the number of single-byte characters the string can hold without
- /// reallocating
- fn capacity(&self) -> uint;
-
- /// Shorten a string to the specified length (which must be <= the current length)
- fn truncate(&mut self, len: uint);
-
- /// Consumes the string, returning the underlying byte buffer.
- ///
- /// The buffer does not have a null terminator.
- fn into_bytes(self) -> ~[u8];
-
- /// Work with the mutable byte buffer and length of a slice.
- ///
- /// The buffer does not have a null terminator.
- ///
- /// The caller must make sure any mutations to this buffer keep the string
- /// valid UTF-8!
- fn as_mut_buf<T>(&mut self, f: |*mut u8, uint| -> T) -> T;
-}
-
-impl OwnedStr for ~str {
- #[inline]
- fn push_str_no_overallocate(&mut self, rhs: &str) {
- let new_cap = self.len() + rhs.len();
- self.reserve(new_cap);
- self.push_str(rhs);
- }
-
- #[inline]
- fn push_str(&mut self, rhs: &str) {
- unsafe {
- raw::push_bytes(self, rhs.as_bytes());
- }
- }
-
- #[inline]
- fn push_char(&mut self, c: char) {
- let cur_len = self.len();
- // may use up to 4 bytes.
- unsafe {
- raw::as_owned_vec(self).reserve_additional(4);
-
- // Attempt to not use an intermediate buffer by just pushing bytes
- // directly onto this string.
- let used = self.as_mut_buf(|buf, _| {
- vec::raw::mut_buf_as_slice(buf.offset(cur_len as int), 4, |slc| {
- c.encode_utf8(slc)
- })
- });
- raw::set_len(self, cur_len + used);
- }
- }
-
- #[inline]
- fn pop_char(&mut self) -> char {
- let end = self.len();
- assert!(end > 0u);
- let CharRange {ch, next} = self.char_range_at_reverse(end);
- unsafe { raw::set_len(self, next); }
- return ch;
- }
-
- #[inline]
- fn shift_char(&mut self) -> char {
- let CharRange {ch, next} = self.char_range_at(0u);
- *self = self.slice(next, self.len()).to_owned();
- return ch;
- }
-
- #[inline]
- fn unshift_char(&mut self, ch: char) {
- // This could be more efficient.
- let mut new_str = ~"";
- new_str.push_char(ch);
- new_str.push_str(*self);
- *self = new_str;
- }
-
- #[inline]
- fn append(self, rhs: &str) -> ~str {
- let mut new_str = self;
- new_str.push_str_no_overallocate(rhs);
- new_str
- }
-
- #[inline]
- fn reserve(&mut self, n: uint) {
- unsafe {
- raw::as_owned_vec(self).reserve(n)
- }
- }
-
- #[inline]
- fn reserve_at_least(&mut self, n: uint) {
- self.reserve(uint::next_power_of_two_opt(n).unwrap_or(n))
- }
-
- #[inline]
- fn capacity(&self) -> uint {
- unsafe {
- let buf: &~[u8] = cast::transmute(self);
- buf.capacity()
- }
- }
-
- #[inline]
- fn truncate(&mut self, len: uint) {
- assert!(len <= self.len());
- assert!(self.is_char_boundary(len));
- unsafe { raw::set_len(self, len); }
- }
-
- #[inline]
- fn into_bytes(self) -> ~[u8] {
- unsafe { cast::transmute(self) }
- }
-
- #[inline]
- fn as_mut_buf<T>(&mut self, f: |*mut u8, uint| -> T) -> T {
- unsafe {
- raw::as_owned_vec(self).as_mut_buf(f)
- }
- }
-}
-
-impl Clone for ~str {
- #[inline]
- fn clone(&self) -> ~str {
- self.to_owned()
- }
-}
-
-impl DeepClone for ~str {
- #[inline]
- fn deep_clone(&self) -> ~str {
- self.to_owned()
- }
-}
-
-impl Clone for @str {
- #[inline]
- fn clone(&self) -> @str {
- *self
- }
-}
-
-impl DeepClone for @str {
- #[inline]
- fn deep_clone(&self) -> @str {
- *self
- }
-}
-
-impl FromIterator<char> for ~str {
- #[inline]
- fn from_iterator<T: Iterator<char>>(iterator: &mut T) -> ~str {
- let (lower, _) = iterator.size_hint();
- let mut buf = with_capacity(lower);
- buf.extend(iterator);
- buf
- }
-}
-
-impl Extendable<char> for ~str {
- #[inline]
- fn extend<T: Iterator<char>>(&mut self, iterator: &mut T) {
- let (lower, _) = iterator.size_hint();
- let reserve = lower + self.len();
- self.reserve_at_least(reserve);
- for ch in *iterator {
- self.push_char(ch)
- }
- }
-}
-
-// This works because every lifetime is a sub-lifetime of 'static
-impl<'self> Default for &'self str {
- fn default() -> &'self str { "" }
-}
-
-impl Default for ~str {
- fn default() -> ~str { ~"" }
-}
-
-impl Default for @str {
- fn default() -> @str { @"" }
-}
-
-#[cfg(test)]
-mod tests {
- use container::Container;
- use option::{None, Some, Option};
- use ptr;
- use str::*;
- use vec;
- use vec::{Vector, ImmutableVector, CopyableVector};
- use cmp::{TotalOrd, Less, Equal, Greater};
- use send_str::{SendStrOwned, SendStrStatic};
- use from_str::from_str;
-
- #[test]
- fn test_eq() {
- assert!((eq(&~"", &~"")));
- assert!((eq(&~"foo", &~"foo")));
- assert!((!eq(&~"foo", &~"bar")));
- }
-
- #[test]
- fn test_eq_slice() {
- assert!((eq_slice("foobar".slice(0, 3), "foo")));
- assert!((eq_slice("barfoo".slice(3, 6), "foo")));
- assert!((!eq_slice("foo1", "foo2")));
- }
-
- #[test]
- fn test_le() {
- assert!("" <= "");
- assert!("" <= "foo");
- assert!("foo" <= "foo");
- assert!("foo" != "bar");
- }
-
- #[test]
- fn test_len() {
- assert_eq!("".len(), 0u);
- assert_eq!("hello world".len(), 11u);
- assert_eq!("\x63".len(), 1u);
- assert_eq!("\xa2".len(), 2u);
- assert_eq!("\u03c0".len(), 2u);
- assert_eq!("\u2620".len(), 3u);
- assert_eq!("\U0001d11e".len(), 4u);
-
- assert_eq!("".char_len(), 0u);
- assert_eq!("hello world".char_len(), 11u);
- assert_eq!("\x63".char_len(), 1u);
- assert_eq!("\xa2".char_len(), 1u);
- assert_eq!("\u03c0".char_len(), 1u);
- assert_eq!("\u2620".char_len(), 1u);
- assert_eq!("\U0001d11e".char_len(), 1u);
- assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
- }
-
- #[test]
- fn test_find() {
- assert_eq!("hello".find('l'), Some(2u));
- assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
- assert!("hello".find('x').is_none());
- assert!("hello".find(|c:char| c == 'x').is_none());
- assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
- assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
- }
-
- #[test]
- fn test_rfind() {
- assert_eq!("hello".rfind('l'), Some(3u));
- assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
- assert!("hello".rfind('x').is_none());
- assert!("hello".rfind(|c:char| c == 'x').is_none());
- assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
- assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
- }
-
- #[test]
- fn test_push_str() {
- let mut s = ~"";
- s.push_str("");
- assert_eq!(s.slice_from(0), "");
- s.push_str("abc");
- assert_eq!(s.slice_from(0), "abc");
- s.push_str("ประเทศไทย中华Việt Nam");
- assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
- }
-
- #[test]
- fn test_append() {
- let mut s = ~"";
- s = s.append("");
- assert_eq!(s.slice_from(0), "");
- s = s.append("abc");
- assert_eq!(s.slice_from(0), "abc");
- s = s.append("ประเทศไทย中华Việt Nam");
- assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
- }
-
- #[test]
- fn test_pop_char() {
- let mut data = ~"ประเทศไทย中华";
- let cc = data.pop_char();
- assert_eq!(~"ประเทศไทย中", data);
- assert_eq!('华', cc);
- }
-
- #[test]
- fn test_pop_char_2() {
- let mut data2 = ~"华";
- let cc2 = data2.pop_char();
- assert_eq!(~"", data2);
- assert_eq!('华', cc2);
- }
-
- #[test]
- #[should_fail]
- fn test_pop_char_fail() {
- let mut data = ~"";
- let _cc3 = data.pop_char();
- }
-
- #[test]
- fn test_push_char() {
- let mut data = ~"ประเทศไทย中";
- data.push_char('华');
- data.push_char('b'); // 1 byte
- data.push_char('¢'); // 2 byte
- data.push_char('€'); // 3 byte
- data.push_char('𤭢'); // 4 byte
- assert_eq!(~"ประเทศไทย中华b¢€𤭢", data);
- }
-
- #[test]
- fn test_shift_char() {
- let mut data = ~"ประเทศไทย中";
- let cc = data.shift_char();
- assert_eq!(~"ระเทศไทย中", data);
- assert_eq!('ป', cc);
- }
-
- #[test]
- fn test_unshift_char() {
- let mut data = ~"ประเทศไทย中";
- data.unshift_char('华');
- assert_eq!(~"华ประเทศไทย中", data);
- }
-
- #[test]
- fn test_collect() {
- let empty = ~"";
- let s: ~str = empty.chars().collect();
- assert_eq!(empty, s);
- let data = ~"ประเทศไทย中";
- let s: ~str = data.chars().collect();
- assert_eq!(data, s);
- }
-
- #[test]
- fn test_extend() {
- let data = ~"ประเทศไทย中";
- let mut cpy = data.clone();
- let other = "abc";
- let mut it = other.chars();
- cpy.extend(&mut it);
- assert_eq!(cpy, data + other);
- }
-
- #[test]
- fn test_clear() {
- let mut empty = ~"";
- empty.clear();
- assert_eq!("", empty.as_slice());
- let mut data = ~"ประเทศไทย中";
- data.clear();
- assert_eq!("", data.as_slice());
- data.push_char('华');
- assert_eq!("华", data.as_slice());
- }
-
- #[test]
- fn test_into_bytes() {
- let data = ~"asdf";
- let buf = data.into_bytes();
- assert_eq!(bytes!("asdf"), buf.as_slice());
- }
-
- #[test]
- fn test_find_str() {
- // byte positions
- assert_eq!("".find_str(""), Some(0u));
- assert!("banana".find_str("apple pie").is_none());
-
- let data = "abcabc";
- assert_eq!(data.slice(0u, 6u).find_str("ab"), Some(0u));
- assert_eq!(data.slice(2u, 6u).find_str("ab"), Some(3u - 2u));
- assert!(data.slice(2u, 4u).find_str("ab").is_none());
-
- let mut data = ~"ประเทศไทย中华Việt Nam";
- data = data + data;
- assert!(data.find_str("ไท华").is_none());
- assert_eq!(data.slice(0u, 43u).find_str(""), Some(0u));
- assert_eq!(data.slice(6u, 43u).find_str(""), Some(6u - 6u));
-
- assert_eq!(data.slice(0u, 43u).find_str("ประ"), Some( 0u));
- assert_eq!(data.slice(0u, 43u).find_str("ทศไ"), Some(12u));
- assert_eq!(data.slice(0u, 43u).find_str("ย中"), Some(24u));
- assert_eq!(data.slice(0u, 43u).find_str("iệt"), Some(34u));
- assert_eq!(data.slice(0u, 43u).find_str("Nam"), Some(40u));
-
- assert_eq!(data.slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
- assert_eq!(data.slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
- assert_eq!(data.slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
- assert_eq!(data.slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
- assert_eq!(data.slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
- }
-
- #[test]
- fn test_slice_chars() {
- fn t(a: &str, b: &str, start: uint) {
- assert_eq!(a.slice_chars(start, start + b.char_len()), b);
- }
- t("", "", 0);
- t("hello", "llo", 2);
- t("hello", "el", 1);
- t("αβλ", "β", 1);
- t("αβλ", "", 3);
- assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
- }
-
- #[test]
- fn test_concat() {
- fn t(v: &[~str], s: &str) {
- assert_eq!(v.concat(), s.to_str());
- }
- t([~"you", ~"know", ~"I'm", ~"no", ~"good"], "youknowI'mnogood");
- let v: &[~str] = [];
- t(v, "");
- t([~"hi"], "hi");
- }
-
- #[test]
- fn test_connect() {
- fn t(v: &[~str], sep: &str, s: &str) {
- assert_eq!(v.connect(sep), s.to_str());
- }
- t([~"you", ~"know", ~"I'm", ~"no", ~"good"],
- " ", "you know I'm no good");
- let v: &[~str] = [];
- t(v, " ", "");
- t([~"hi"], " ", "hi");
- }
-
- #[test]
- fn test_concat_slices() {
- fn t(v: &[&str], s: &str) {
- assert_eq!(v.concat(), s.to_str());
- }
- t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
- let v: &[&str] = [];
- t(v, "");
- t(["hi"], "hi");
- }
-
- #[test]
- fn test_connect_slices() {
- fn t(v: &[&str], sep: &str, s: &str) {
- assert_eq!(v.connect(sep), s.to_str());
- }
- t(["you", "know", "I'm", "no", "good"],
- " ", "you know I'm no good");
- t([], " ", "");
- t(["hi"], " ", "hi");
- }
-
- #[test]
- fn test_repeat() {
- assert_eq!("x".repeat(4), ~"xxxx");
- assert_eq!("hi".repeat(4), ~"hihihihi");
- assert_eq!("ไท华".repeat(3), ~"ไท华ไท华ไท华");
- assert_eq!("".repeat(4), ~"");
- assert_eq!("hi".repeat(0), ~"");
- }
-
- #[test]
- fn test_unsafe_slice() {
- assert_eq!("ab", unsafe {raw::slice_bytes("abc", 0, 2)});
- assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
- assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
- fn a_million_letter_a() -> ~str {
- let mut i = 0;
- let mut rs = ~"";
- while i < 100000 { rs.push_str("aaaaaaaaaa"); i += 1; }
- rs
- }
- fn half_a_million_letter_a() -> ~str {
- let mut i = 0;
- let mut rs = ~"";
- while i < 100000 { rs.push_str("aaaaa"); i += 1; }
- rs
- }
- let letters = a_million_letter_a();
- assert!(half_a_million_letter_a() ==
- unsafe {raw::slice_bytes(letters, 0u, 500000)}.to_owned());
- }
-
- #[test]
- fn test_starts_with() {
- assert!(("".starts_with("")));
- assert!(("abc".starts_with("")));
- assert!(("abc".starts_with("a")));
- assert!((!"a".starts_with("abc")));
- assert!((!"".starts_with("abc")));
- assert!((!"ödd".starts_with("-")));
- assert!(("ödd".starts_with("öd")));
- }
-
- #[test]
- fn test_ends_with() {
- assert!(("".ends_with("")));
- assert!(("abc".ends_with("")));
- assert!(("abc".ends_with("c")));
- assert!((!"a".ends_with("abc")));
- assert!((!"".ends_with("abc")));
- assert!((!"ddö".ends_with("-")));
- assert!(("ddö".ends_with("dö")));
- }
-
- #[test]
- fn test_is_empty() {
- assert!("".is_empty());
- assert!(!"a".is_empty());
- }
-
- #[test]
- fn test_replace() {
- let a = "a";
- assert_eq!("".replace(a, "b"), ~"");
- assert_eq!("a".replace(a, "b"), ~"b");
- assert_eq!("ab".replace(a, "b"), ~"bb");
- let test = "test";
- assert!(" test test ".replace(test, "toast") ==
- ~" toast toast ");
- assert_eq!(" test test ".replace(test, ""), ~" ");
- }
-
- #[test]
- fn test_replace_2a() {
- let data = ~"ประเทศไทย中华";
- let repl = ~"دولة الكويت";
-
- let a = ~"ประเ";
- let A = ~"دولة الكويتทศไทย中华";
- assert_eq!(data.replace(a, repl), A);
- }
-
- #[test]
- fn test_replace_2b() {
- let data = ~"ประเทศไทย中华";
- let repl = ~"دولة الكويت";
-
- let b = ~"ะเ";
- let B = ~"ปรدولة الكويتทศไทย中华";
- assert_eq!(data.replace(b, repl), B);
- }
-
- #[test]
- fn test_replace_2c() {
- let data = ~"ประเทศไทย中华";
- let repl = ~"دولة الكويت";
-
- let c = ~"中华";
- let C = ~"ประเทศไทยدولة الكويت";
- assert_eq!(data.replace(c, repl), C);
- }
-
- #[test]
- fn test_replace_2d() {
- let data = ~"ประเทศไทย中华";
- let repl = ~"دولة الكويت";
-
- let d = ~"ไท华";
- assert_eq!(data.replace(d, repl), data);
- }
-
- #[test]
- fn test_slice() {
- assert_eq!("ab", "abc".slice(0, 2));
- assert_eq!("bc", "abc".slice(1, 3));
- assert_eq!("", "abc".slice(1, 1));
- assert_eq!("\u65e5", "\u65e5\u672c".slice(0, 3));
-
- let data = "ประเทศไทย中华";
- assert_eq!("ป", data.slice(0, 3));
- assert_eq!("ร", data.slice(3, 6));
- assert_eq!("", data.slice(3, 3));
- assert_eq!("华", data.slice(30, 33));
-
- fn a_million_letter_X() -> ~str {
- let mut i = 0;
- let mut rs = ~"";
- while i < 100000 {
- push_str(&mut rs, "华华华华华华华华华华");
- i += 1;
- }
- rs
- }
- fn half_a_million_letter_X() -> ~str {
- let mut i = 0;
- let mut rs = ~"";
- while i < 100000 { push_str(&mut rs, "华华华华华"); i += 1; }
- rs
- }
- let letters = a_million_letter_X();
- assert!(half_a_million_letter_X() ==
- letters.slice(0u, 3u * 500000u).to_owned());
- }
-
- #[test]
- fn test_slice_2() {
- let ss = "中华Việt Nam";
-
- assert_eq!("华", ss.slice(3u, 6u));
- assert_eq!("Việt Nam", ss.slice(6u, 16u));
-
- assert_eq!("ab", "abc".slice(0u, 2u));
- assert_eq!("bc", "abc".slice(1u, 3u));
- assert_eq!("", "abc".slice(1u, 1u));
-
- assert_eq!("中", ss.slice(0u, 3u));
- assert_eq!("华V", ss.slice(3u, 7u));
- assert_eq!("", ss.slice(3u, 3u));
- /*0: 中
- 3: 华
- 6: V
- 7: i
- 8: ệ
- 11: t
- 12:
- 13: N
- 14: a
- 15: m */
- }
-
- #[test]
- #[should_fail]
- fn test_slice_fail() {
- "中华Việt Nam".slice(0u, 2u);
- }
-
- #[test]
- fn test_slice_from() {
- assert_eq!("abcd".slice_from(0), "abcd");
- assert_eq!("abcd".slice_from(2), "cd");
- assert_eq!("abcd".slice_from(4), "");
- }
- #[test]
- fn test_slice_to() {
- assert_eq!("abcd".slice_to(0), "");
- assert_eq!("abcd".slice_to(2), "ab");
- assert_eq!("abcd".slice_to(4), "abcd");
- }
-
- #[test]
- fn test_trim_left_chars() {
- let v: &[char] = &[];
- assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
- assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
- assert_eq!(" *** *** ".trim_left_chars(& &['*', ' ']), "");
- assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
-
- assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
- assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
- assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
- }
-
- #[test]
- fn test_trim_right_chars() {
- let v: &[char] = &[];
- assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
- assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
- assert_eq!(" *** *** ".trim_right_chars(& &['*', ' ']), "");
- assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
-
- assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
- assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
- assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
- }
-
- #[test]
- fn test_trim_chars() {
- let v: &[char] = &[];
- assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
- assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
- assert_eq!(" *** *** ".trim_chars(& &['*', ' ']), "");
- assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
-
- assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
- assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
- assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
- }
-
- #[test]
- fn test_trim_left() {
- assert_eq!("".trim_left(), "");
- assert_eq!("a".trim_left(), "a");
- assert_eq!(" ".trim_left(), "");
- assert_eq!(" blah".trim_left(), "blah");
- assert_eq!(" \u3000 wut".trim_left(), "wut");
- assert_eq!("hey ".trim_left(), "hey ");
- }
-
- #[test]
- fn test_trim_right() {
- assert_eq!("".trim_right(), "");
- assert_eq!("a".trim_right(), "a");
- assert_eq!(" ".trim_right(), "");
- assert_eq!("blah ".trim_right(), "blah");
- assert_eq!("wut \u3000 ".trim_right(), "wut");
- assert_eq!(" hey".trim_right(), " hey");
- }
-
- #[test]
- fn test_trim() {
- assert_eq!("".trim(), "");
- assert_eq!("a".trim(), "a");
- assert_eq!(" ".trim(), "");
- assert_eq!(" blah ".trim(), "blah");
- assert_eq!("\nwut \u3000 ".trim(), "wut");
- assert_eq!(" hey dude ".trim(), "hey dude");
- }
-
- #[test]
- fn test_is_whitespace() {
- assert!("".is_whitespace());
- assert!(" ".is_whitespace());
- assert!("\u2009".is_whitespace()); // Thin space
- assert!(" \n\t ".is_whitespace());
- assert!(!" _ ".is_whitespace());
- }
-
- #[test]
- fn test_push_byte() {
- let mut s = ~"ABC";
- unsafe{raw::push_byte(&mut s, 'D' as u8)};
- assert_eq!(s, ~"ABCD");
- }
-
- #[test]
- fn test_shift_byte() {
- let mut s = ~"ABC";
- let b = unsafe{raw::shift_byte(&mut s)};
- assert_eq!(s, ~"BC");
- assert_eq!(b, 65u8);
- }
-
- #[test]
- fn test_pop_byte() {
- let mut s = ~"ABC";
- let b = unsafe{raw::pop_byte(&mut s)};
- assert_eq!(s, ~"AB");
- assert_eq!(b, 67u8);
- }
-
- #[test]
- fn test_unsafe_from_utf8() {
- let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8];
- let b = unsafe { raw::from_utf8(a) };
- assert_eq!(b, ~"AAAAAAA");
- }
-
- #[test]
- fn test_from_utf8() {
- let ss = ~"ศไทย中华Việt Nam";
- let bb = ~[0xe0_u8, 0xb8_u8, 0xa8_u8,
- 0xe0_u8, 0xb9_u8, 0x84_u8,
- 0xe0_u8, 0xb8_u8, 0x97_u8,
- 0xe0_u8, 0xb8_u8, 0xa2_u8,
- 0xe4_u8, 0xb8_u8, 0xad_u8,
- 0xe5_u8, 0x8d_u8, 0x8e_u8,
- 0x56_u8, 0x69_u8, 0xe1_u8,
- 0xbb_u8, 0x87_u8, 0x74_u8,
- 0x20_u8, 0x4e_u8, 0x61_u8,
- 0x6d_u8];
-
-
- assert_eq!(ss, from_utf8(bb));
- assert_eq!(~"𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰",
- from_utf8(bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰")));
- }
-
- #[test]
- fn test_is_utf8() {
- // deny overlong encodings
- assert!(!is_utf8([0xc0, 0x80]));
- assert!(!is_utf8([0xc0, 0xae]));
- assert!(!is_utf8([0xe0, 0x80, 0x80]));
- assert!(!is_utf8([0xe0, 0x80, 0xaf]));
- assert!(!is_utf8([0xe0, 0x81, 0x81]));
- assert!(!is_utf8([0xf0, 0x82, 0x82, 0xac]));
- assert!(!is_utf8([0xf4, 0x90, 0x80, 0x80]));
-
- // deny surrogates
- assert!(!is_utf8([0xED, 0xA0, 0x80]));
- assert!(!is_utf8([0xED, 0xBF, 0xBF]));
-
- assert!(is_utf8([0xC2, 0x80]));
- assert!(is_utf8([0xDF, 0xBF]));
- assert!(is_utf8([0xE0, 0xA0, 0x80]));
- assert!(is_utf8([0xED, 0x9F, 0xBF]));
- assert!(is_utf8([0xEE, 0x80, 0x80]));
- assert!(is_utf8([0xEF, 0xBF, 0xBF]));
- assert!(is_utf8([0xF0, 0x90, 0x80, 0x80]));
- assert!(is_utf8([0xF4, 0x8F, 0xBF, 0xBF]));
- }
-
-
- #[test]
- fn test_from_utf8_fail() {
- use str::not_utf8::cond;
-
- let bb = ~[0xff_u8, 0xb8_u8, 0xa8_u8,
- 0xe0_u8, 0xb9_u8, 0x84_u8,
- 0xe0_u8, 0xb8_u8, 0x97_u8,
- 0xe0_u8, 0xb8_u8, 0xa2_u8,
- 0xe4_u8, 0xb8_u8, 0xad_u8,
- 0xe5_u8, 0x8d_u8, 0x8e_u8,
- 0x56_u8, 0x69_u8, 0xe1_u8,
- 0xbb_u8, 0x87_u8, 0x74_u8,
- 0x20_u8, 0x4e_u8, 0x61_u8,
- 0x6d_u8];
-
- let mut error_happened = false;
- let _x = cond.trap(|err| {
- assert_eq!(err, ~"from_utf8: input is not UTF-8; first bad byte is 255");
- error_happened = true;
- ~""
- }).inside(|| from_utf8(bb));
- assert!(error_happened);
- }
-
- #[test]
- fn test_raw_from_c_str() {
- unsafe {
- let a = ~[65, 65, 65, 65, 65, 65, 65, 0];
- let b = vec::raw::to_ptr(a);
- let c = raw::from_c_str(b);
- assert_eq!(c, ~"AAAAAAA");
- }
- }
-
- #[test]
- fn test_as_bytes() {
- // no null
- let v = [
- 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
- 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
- 109
- ];
- assert_eq!("".as_bytes(), &[]);
- assert_eq!("abc".as_bytes(), &['a' as u8, 'b' as u8, 'c' as u8]);
- assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
- }
-
- #[test]
- #[should_fail]
- fn test_as_bytes_fail() {
- // Don't double free. (I'm not sure if this exercises the
- // original problem code path anymore.)
- let s = ~"";
- let _bytes = s.as_bytes();
- fail!();
- }
-
- #[test]
- fn test_as_imm_buf() {
- "".as_imm_buf(|_, len| assert_eq!(len, 0));
-
- "hello".as_imm_buf(|buf, len| {
- assert_eq!(len, 5);
- unsafe {
- assert_eq!(*ptr::offset(buf, 0), 'h' as u8);
- assert_eq!(*ptr::offset(buf, 1), 'e' as u8);
- assert_eq!(*ptr::offset(buf, 2), 'l' as u8);
- assert_eq!(*ptr::offset(buf, 3), 'l' as u8);
- assert_eq!(*ptr::offset(buf, 4), 'o' as u8);
- }
- })
- }
-
- #[test]
- fn test_subslice_offset() {
- let a = "kernelsprite";
- let b = a.slice(7, a.len());
- let c = a.slice(0, a.len() - 6);
- assert_eq!(a.subslice_offset(b), 7);
- assert_eq!(a.subslice_offset(c), 0);
-
- let string = "a\nb\nc";
- let mut lines = ~[];
- for line in string.lines() { lines.push(line) }
- assert_eq!(string.subslice_offset(lines[0]), 0);
- assert_eq!(string.subslice_offset(lines[1]), 2);
- assert_eq!(string.subslice_offset(lines[2]), 4);
- }
-
- #[test]
- #[should_fail]
- fn test_subslice_offset_2() {
- let a = "alchemiter";
- let b = "cruxtruder";
- a.subslice_offset(b);
- }
-
- #[test]
- fn vec_str_conversions() {
- let s1: ~str = ~"All mimsy were the borogoves";
-
- let v: ~[u8] = s1.as_bytes().to_owned();
- let s2: ~str = from_utf8(v);
- let mut i: uint = 0u;
- let n1: uint = s1.len();
- let n2: uint = v.len();
- assert_eq!(n1, n2);
- while i < n1 {
- let a: u8 = s1[i];
- let b: u8 = s2[i];
- debug!("{}", a);
- debug!("{}", b);
- assert_eq!(a, b);
- i += 1u;
- }
- }
-
- #[test]
- fn test_contains() {
- assert!("abcde".contains("bcd"));
- assert!("abcde".contains("abcd"));
- assert!("abcde".contains("bcde"));
- assert!("abcde".contains(""));
- assert!("".contains(""));
- assert!(!"abcde".contains("def"));
- assert!(!"".contains("a"));
-
- let data = ~"ประเทศไทย中华Việt Nam";
- assert!(data.contains("ประเ"));
- assert!(data.contains("ะเ"));
- assert!(data.contains("中华"));
- assert!(!data.contains("ไท华"));
- }
-
- #[test]
- fn test_contains_char() {
- assert!("abc".contains_char('b'));
- assert!("a".contains_char('a'));
- assert!(!"abc".contains_char('d'));
- assert!(!"".contains_char('a'));
- }
-
- #[test]
- fn test_utf16() {
- let pairs =
- [(~"𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n",
- ~[0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
- 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
- 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
- 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
-
- (~"𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n",
- ~[0xd801_u16, 0xdc12_u16, 0xd801_u16,
- 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
- 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
- 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
- 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
- 0x000a_u16]),
-
- (~"𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n",
- ~[0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
- 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
- 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
- 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
- 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
- 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
- 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
-
- (~"𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n",
- ~[0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
- 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
- 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
- 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
- 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
- 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
- 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
- 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
- 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
- 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
- 0x000a_u16 ]) ];
-
- for p in pairs.iter() {
- let (s, u) = (*p).clone();
- assert!(s.to_utf16() == u);
- assert!(from_utf16(u) == s);
- assert!(from_utf16(s.to_utf16()) == s);
- assert!(from_utf16(u).to_utf16() == u);
- }
- }
-
- #[test]
- fn test_char_at() {
- let s = ~"ศไทย中华Việt Nam";
- let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
- let mut pos = 0;
- for ch in v.iter() {
- assert!(s.char_at(pos) == *ch);
- pos += from_char(*ch).len();
- }
- }
-
- #[test]
- fn test_char_at_reverse() {
- let s = ~"ศไทย中华Việt Nam";
- let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
- let mut pos = s.len();
- for ch in v.rev_iter() {
- assert!(s.char_at_reverse(pos) == *ch);
- pos -= from_char(*ch).len();
- }
- }
-
- #[test]
- fn test_escape_unicode() {
- assert_eq!("abc".escape_unicode(), ~"\\x61\\x62\\x63");
- assert_eq!("a c".escape_unicode(), ~"\\x61\\x20\\x63");
- assert_eq!("\r\n\t".escape_unicode(), ~"\\x0d\\x0a\\x09");
- assert_eq!("'\"\\".escape_unicode(), ~"\\x27\\x22\\x5c");
- assert_eq!("\x00\x01\xfe\xff".escape_unicode(), ~"\\x00\\x01\\xfe\\xff");
- assert_eq!("\u0100\uffff".escape_unicode(), ~"\\u0100\\uffff");
- assert_eq!("\U00010000\U0010ffff".escape_unicode(), ~"\\U00010000\\U0010ffff");
- assert_eq!("ab\ufb00".escape_unicode(), ~"\\x61\\x62\\ufb00");
- assert_eq!("\U0001d4ea\r".escape_unicode(), ~"\\U0001d4ea\\x0d");
- }
-
- #[test]
- fn test_escape_default() {
- assert_eq!("abc".escape_default(), ~"abc");
- assert_eq!("a c".escape_default(), ~"a c");
- assert_eq!("\r\n\t".escape_default(), ~"\\r\\n\\t");
- assert_eq!("'\"\\".escape_default(), ~"\\'\\\"\\\\");
- assert_eq!("\u0100\uffff".escape_default(), ~"\\u0100\\uffff");
- assert_eq!("\U00010000\U0010ffff".escape_default(), ~"\\U00010000\\U0010ffff");
- assert_eq!("ab\ufb00".escape_default(), ~"ab\\ufb00");
- assert_eq!("\U0001d4ea\r".escape_default(), ~"\\U0001d4ea\\r");
- }
-
- #[test]
- fn test_to_managed() {
- assert_eq!("abc".to_managed(), @"abc");
- assert_eq!("abcdef".slice(1, 5).to_managed(), @"bcde");
- }
-
- #[test]
- fn test_total_ord() {
- "1234".cmp(& &"123") == Greater;
- "123".cmp(& &"1234") == Less;
- "1234".cmp(& &"1234") == Equal;
- "12345555".cmp(& &"123456") == Less;
- "22".cmp(& &"1234") == Greater;
- }
-
- #[test]
- fn test_char_range_at() {
- let data = ~"b¢€𤭢𤭢€¢b";
- assert_eq!('b', data.char_range_at(0).ch);
- assert_eq!('¢', data.char_range_at(1).ch);
- assert_eq!('€', data.char_range_at(3).ch);
- assert_eq!('𤭢', data.char_range_at(6).ch);
- assert_eq!('𤭢', data.char_range_at(10).ch);
- assert_eq!('€', data.char_range_at(14).ch);
- assert_eq!('¢', data.char_range_at(17).ch);
- assert_eq!('b', data.char_range_at(19).ch);
- }
-
- #[test]
- fn test_char_range_at_reverse_underflow() {
- assert_eq!("abc".char_range_at_reverse(0).next, 0);
- }
-
- #[test]
- fn test_add() {
- #[allow(unnecessary_allocation)];
- macro_rules! t (
- ($s1:expr, $s2:expr, $e:expr) => { {
- let s1 = $s1;
- let s2 = $s2;
- let e = $e;
- assert_eq!(s1 + s2, e.to_owned());
- assert_eq!(s1.to_owned() + s2, e.to_owned());
- assert_eq!(s1.to_managed() + s2, e.to_owned());
- } }
- );
-
- t!("foo", "bar", "foobar");
- t!("foo", @"bar", "foobar");
- t!("foo", ~"bar", "foobar");
- t!("ศไทย中", "华Việt Nam", "ศไทย中华Việt Nam");
- t!("ศไทย中", @"华Việt Nam", "ศไทย中华Việt Nam");
- t!("ศไทย中", ~"华Việt Nam", "ศไทย中华Việt Nam");
- }
-
- #[test]
- fn test_iterator() {
- use iter::*;
- let s = ~"ศไทย中华Việt Nam";
- let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
- let mut pos = 0;
- let mut it = s.chars();
-
- for c in it {
- assert_eq!(c, v[pos]);
- pos += 1;
- }
- assert_eq!(pos, v.len());
- }
-
- #[test]
- fn test_rev_iterator() {
- use iter::*;
- let s = ~"ศไทย中华Việt Nam";
- let v = ~['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
- let mut pos = 0;
- let mut it = s.chars_rev();
-
- for c in it {
- assert_eq!(c, v[pos]);
- pos += 1;
- }
- assert_eq!(pos, v.len());
- }
-
- #[test]
- fn test_iterator_clone() {
- let s = "ศไทย中华Việt Nam";
- let mut it = s.chars();
- it.next();
- assert!(it.zip(it.clone()).all(|(x,y)| x == y));
- }
-
- #[test]
- fn test_bytesator() {
- let s = ~"ศไทย中华Việt Nam";
- let v = [
- 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
- 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
- 109
- ];
- let mut pos = 0;
-
- for b in s.bytes() {
- assert_eq!(b, v[pos]);
- pos += 1;
- }
- }
-
- #[test]
- fn test_bytes_revator() {
- let s = ~"ศไทย中华Việt Nam";
- let v = [
- 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
- 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
- 109
- ];
- let mut pos = v.len();
-
- for b in s.bytes_rev() {
- pos -= 1;
- assert_eq!(b, v[pos]);
- }
- }
-
- #[test]
- fn test_char_indicesator() {
- use iter::*;
- let s = "ศไทย中华Việt Nam";
- let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
- let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
- let mut pos = 0;
- let mut it = s.char_indices();
-
- for c in it {
- assert_eq!(c, (p[pos], v[pos]));
- pos += 1;
- }
- assert_eq!(pos, v.len());
- assert_eq!(pos, p.len());
- }
-
- #[test]
- fn test_char_indices_revator() {
- use iter::*;
- let s = "ศไทย中华Việt Nam";
- let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
- let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
- let mut pos = 0;
- let mut it = s.char_indices_rev();
-
- for c in it {
- assert_eq!(c, (p[pos], v[pos]));
- pos += 1;
- }
- assert_eq!(pos, v.len());
- assert_eq!(pos, p.len());
- }
-
- #[test]
- fn test_split_char_iterator() {
- let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
- let split: ~[&str] = data.split(' ').collect();
- assert_eq!( split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
- let mut rsplit: ~[&str] = data.rsplit(' ').collect();
- rsplit.reverse();
- assert_eq!(rsplit, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
- let split: ~[&str] = data.split(|c: char| c == ' ').collect();
- assert_eq!( split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
- let mut rsplit: ~[&str] = data.rsplit(|c: char| c == ' ').collect();
- rsplit.reverse();
- assert_eq!(rsplit, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
- // Unicode
- let split: ~[&str] = data.split('ä').collect();
- assert_eq!( split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
- let mut rsplit: ~[&str] = data.rsplit('ä').collect();
- rsplit.reverse();
- assert_eq!(rsplit, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
- let split: ~[&str] = data.split(|c: char| c == 'ä').collect();
- assert_eq!( split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
- let mut rsplit: ~[&str] = data.rsplit(|c: char| c == 'ä').collect();
- rsplit.reverse();
- assert_eq!(rsplit, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
- }
-
- #[test]
- fn test_splitn_char_iterator() {
- let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
- let split: ~[&str] = data.splitn(' ', 3).collect();
- assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
- let split: ~[&str] = data.splitn(|c: char| c == ' ', 3).collect();
- assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
- // Unicode
- let split: ~[&str] = data.splitn('ä', 3).collect();
- assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-
- let split: ~[&str] = data.splitn(|c: char| c == 'ä', 3).collect();
- assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
- }
-
- #[test]
- fn test_rsplitn_char_iterator() {
- let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
- let mut split: ~[&str] = data.rsplitn(' ', 3).collect();
- split.reverse();
- assert_eq!(split, ~["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
-
- let mut split: ~[&str] = data.rsplitn(|c: char| c == ' ', 3).collect();
- split.reverse();
- assert_eq!(split, ~["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
-
- // Unicode
- let mut split: ~[&str] = data.rsplitn('ä', 3).collect();
- split.reverse();
- assert_eq!(split, ~["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
-
- let mut split: ~[&str] = data.rsplitn(|c: char| c == 'ä', 3).collect();
- split.reverse();
- assert_eq!(split, ~["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
- }
-
- #[test]
- fn test_split_char_iterator_no_trailing() {
- let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
- let split: ~[&str] = data.split('\n').collect();
- assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb", ""]);
-
- let split: ~[&str] = data.split_terminator('\n').collect();
- assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb"]);
- }
-
- #[test]
- fn test_rev_split_char_iterator_no_trailing() {
- let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
- let mut split: ~[&str] = data.split('\n').invert().collect();
- split.reverse();
- assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb", ""]);
-
- let mut split: ~[&str] = data.split_terminator('\n').invert().collect();
- split.reverse();
- assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb"]);
- }
-
- #[test]
- fn test_words() {
- let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
- let words: ~[&str] = data.words().collect();
- assert_eq!(words, ~["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
- }
-
- #[test]
- fn test_nfd_chars() {
- assert_eq!("abc".nfd_chars().collect::<~str>(), ~"abc");
- assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<~str>(), ~"d\u0307\u01c4");
- assert_eq!("\u2026".nfd_chars().collect::<~str>(), ~"\u2026");
- assert_eq!("\u2126".nfd_chars().collect::<~str>(), ~"\u03a9");
- assert_eq!("\u1e0b\u0323".nfd_chars().collect::<~str>(), ~"d\u0323\u0307");
- assert_eq!("\u1e0d\u0307".nfd_chars().collect::<~str>(), ~"d\u0323\u0307");
- assert_eq!("a\u0301".nfd_chars().collect::<~str>(), ~"a\u0301");
- assert_eq!("\u0301a".nfd_chars().collect::<~str>(), ~"\u0301a");
- assert_eq!("\ud4db".nfd_chars().collect::<~str>(), ~"\u1111\u1171\u11b6");
- assert_eq!("\uac1c".nfd_chars().collect::<~str>(), ~"\u1100\u1162");
- }
-
- #[test]
- fn test_nfkd_chars() {
- assert_eq!("abc".nfkd_chars().collect::<~str>(), ~"abc");
- assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<~str>(), ~"d\u0307DZ\u030c");
- assert_eq!("\u2026".nfkd_chars().collect::<~str>(), ~"...");
- assert_eq!("\u2126".nfkd_chars().collect::<~str>(), ~"\u03a9");
- assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<~str>(), ~"d\u0323\u0307");
- assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<~str>(), ~"d\u0323\u0307");
- assert_eq!("a\u0301".nfkd_chars().collect::<~str>(), ~"a\u0301");
- assert_eq!("\u0301a".nfkd_chars().collect::<~str>(), ~"\u0301a");
- assert_eq!("\ud4db".nfkd_chars().collect::<~str>(), ~"\u1111\u1171\u11b6");
- assert_eq!("\uac1c".nfkd_chars().collect::<~str>(), ~"\u1100\u1162");
- }
-
- #[test]
- fn test_lines() {
- let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
- let lines: ~[&str] = data.lines().collect();
- assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
-
- let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
- let lines: ~[&str] = data.lines().collect();
- assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
- }
-
- #[test]
- fn test_split_strator() {
- fn t<'a>(s: &str, sep: &'a str, u: ~[&str]) {
- let v: ~[&str] = s.split_str(sep).collect();
- assert_eq!(v, u);
- }
- t("--1233345--", "12345", ~["--1233345--"]);
- t("abc::hello::there", "::", ~["abc", "hello", "there"]);
- t("::hello::there", "::", ~["", "hello", "there"]);
- t("hello::there::", "::", ~["hello", "there", ""]);
- t("::hello::there::", "::", ~["", "hello", "there", ""]);
- t("ประเทศไทย中华Việt Nam", "中华", ~["ประเทศไทย", "Việt Nam"]);
- t("zzXXXzzYYYzz", "zz", ~["", "XXX", "YYY", ""]);
- t("zzXXXzYYYz", "XXX", ~["zz", "zYYYz"]);
- t(".XXX.YYY.", ".", ~["", "XXX", "YYY", ""]);
- t("", ".", ~[""]);
- t("zz", "zz", ~["",""]);
- t("ok", "z", ~["ok"]);
- t("zzz", "zz", ~["","z"]);
- t("zzzzz", "zz", ~["","","z"]);
- }
-
- #[test]
- fn test_str_default() {
- use default::Default;
- fn t<S: Default + Str>() {
- let s: S = Default::default();
- assert_eq!(s.as_slice(), "");
- }
-
- t::<&str>();
- t::<@str>();
- t::<~str>();
- }
-
- #[test]
- fn test_str_container() {
- fn sum_len<S: Container>(v: &[S]) -> uint {
- v.iter().map(|x| x.len()).sum()
- }
-
- let s = ~"01234";
- assert_eq!(5, sum_len(["012", "", "34"]));
- assert_eq!(5, sum_len([@"01", @"2", @"34", @""]));
- assert_eq!(5, sum_len([~"01", ~"2", ~"34", ~""]));
- assert_eq!(5, sum_len([s.as_slice()]));
- }
-
- #[test]
- fn test_str_truncate() {
- let mut s = ~"12345";
- s.truncate(5);
- assert_eq!(s.as_slice(), "12345");
- s.truncate(3);
- assert_eq!(s.as_slice(), "123");
- s.truncate(0);
- assert_eq!(s.as_slice(), "");
-
- let mut s = ~"12345";
- let p = s.as_imm_buf(|p,_| p);
- s.truncate(3);
- s.push_str("6");
- let p_ = s.as_imm_buf(|p,_| p);
- assert_eq!(p_, p);
- }
-
- #[test]
- #[should_fail]
- fn test_str_truncate_invalid_len() {
- let mut s = ~"12345";
- s.truncate(6);
- }
-
- #[test]
- #[should_fail]
- fn test_str_truncate_split_codepoint() {
- let mut s = ~"\u00FC"; // ü
- s.truncate(1);
- }
-
- #[test]
- fn test_str_from_utf8_slice() {
- let xs = bytes!("hello");
- assert_eq!(from_utf8_slice(xs), "hello");
-
- let xs = bytes!("ศไทย中华Việt Nam");
- assert_eq!(from_utf8_slice(xs), "ศไทย中华Việt Nam");
- }
-
- #[test]
- #[should_fail]
- fn test_str_from_utf8_slice_invalid() {
- let xs = bytes!("hello", 0xff);
- let _ = from_utf8_slice(xs);
- }
-
- #[test]
- fn test_str_from_utf8_slice_opt() {
- let xs = bytes!("hello");
- assert_eq!(from_utf8_slice_opt(xs), Some("hello"));
-
- let xs = bytes!("ศไทย中华Việt Nam");
- assert_eq!(from_utf8_slice_opt(xs), Some("ศไทย中华Việt Nam"));
-
- let xs = bytes!("hello", 0xff);
- assert_eq!(from_utf8_slice_opt(xs), None);
- }
-
- #[test]
- fn test_str_from_utf8() {
- let xs = bytes!("hello");
- assert_eq!(from_utf8(xs), ~"hello");
-
- let xs = bytes!("ศไทย中华Việt Nam");
- assert_eq!(from_utf8(xs), ~"ศไทย中华Việt Nam");
- }
-
- #[test]
- fn test_str_from_utf8_opt() {
- let xs = bytes!("hello").to_owned();
- assert_eq!(from_utf8_opt(xs), Some(~"hello"));
-
- let xs = bytes!("ศไทย中华Việt Nam");
- assert_eq!(from_utf8_opt(xs), Some(~"ศไทย中华Việt Nam"));
-
- let xs = bytes!("hello", 0xff);
- assert_eq!(from_utf8_opt(xs), None);
- }
-
- #[test]
- fn test_str_from_utf8_owned() {
- let xs = bytes!("hello").to_owned();
- assert_eq!(from_utf8_owned(xs), ~"hello");
-
- let xs = bytes!("ศไทย中华Việt Nam").to_owned();
- assert_eq!(from_utf8_owned(xs), ~"ศไทย中华Việt Nam");
- }
-
- #[test]
- fn test_str_from_utf8_owned_opt() {
- let xs = bytes!("hello").to_owned();
- assert_eq!(from_utf8_owned_opt(xs), Some(~"hello"));
-
- let xs = bytes!("ศไทย中华Việt Nam").to_owned();
- assert_eq!(from_utf8_owned_opt(xs), Some(~"ศไทย中华Việt Nam"));
-
- let xs = bytes!("hello", 0xff).to_owned();
- assert_eq!(from_utf8_owned_opt(xs), None);
- }
-
- #[test]
- fn test_to_send_str() {
- assert_eq!("abcde".to_send_str(), SendStrStatic("abcde"));
- assert_eq!("abcde".to_send_str(), SendStrOwned(~"abcde"));
- }
-
- #[test]
- fn test_from_str() {
- let owned: Option<~str> = from_str(&"string");
- assert_eq!(owned, Some(~"string"));
- let managed: Option<@str> = from_str(&"string");
- assert_eq!(managed, Some(@"string"));
- }
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
- use super::*;
- use prelude::*;
-
- #[bench]
- fn char_iterator(bh: &mut BenchHarness) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let len = s.char_len();
-
- bh.iter(|| assert_eq!(s.chars().len(), len));
- }
-
- #[bench]
- fn char_iterator_ascii(bh: &mut BenchHarness) {
- let s = "Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb";
- let len = s.char_len();
-
- bh.iter(|| assert_eq!(s.chars().len(), len));
- }
-
- #[bench]
- fn char_iterator_rev(bh: &mut BenchHarness) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let len = s.char_len();
-
- bh.iter(|| assert_eq!(s.chars_rev().len(), len));
- }
-
- #[bench]
- fn char_indicesator(bh: &mut BenchHarness) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let len = s.char_len();
-
- bh.iter(|| assert_eq!(s.char_indices().len(), len));
- }
-
- #[bench]
- fn char_indicesator_rev(bh: &mut BenchHarness) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let len = s.char_len();
-
- bh.iter(|| assert_eq!(s.char_indices_rev().len(), len));
- }
-
- #[bench]
- fn split_unicode_ascii(bh: &mut BenchHarness) {
- let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
- bh.iter(|| assert_eq!(s.split('V').len(), 3));
- }
-
- #[bench]
- fn split_unicode_not_ascii(bh: &mut BenchHarness) {
- struct NotAscii(char);
- impl CharEq for NotAscii {
- fn matches(&self, c: char) -> bool {
- **self == c
- }
- fn only_ascii(&self) -> bool { false }
- }
- let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
- bh.iter(|| assert_eq!(s.split(NotAscii('V')).len(), 3));
- }
-
-
- #[bench]
- fn split_ascii(bh: &mut BenchHarness) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').len();
-
- bh.iter(|| assert_eq!(s.split(' ').len(), len));
- }
-
- #[bench]
- fn split_not_ascii(bh: &mut BenchHarness) {
- struct NotAscii(char);
- impl CharEq for NotAscii {
- #[inline]
- fn matches(&self, c: char) -> bool { **self == c }
- fn only_ascii(&self) -> bool { false }
- }
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').len();
-
- bh.iter(|| assert_eq!(s.split(NotAscii(' ')).len(), len));
- }
-
- #[bench]
- fn split_extern_fn(bh: &mut BenchHarness) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').len();
- fn pred(c: char) -> bool { c == ' ' }
-
- bh.iter(|| assert_eq!(s.split(pred).len(), len));
- }
-
- #[bench]
- fn split_closure(bh: &mut BenchHarness) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').len();
-
- bh.iter(|| assert_eq!(s.split(|c: char| c == ' ').len(), len));
- }
-
- #[bench]
- fn split_slice(bh: &mut BenchHarness) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').len();
-
- bh.iter(|| assert_eq!(s.split(&[' ']).len(), len));
- }
-
- #[bench]
- fn is_utf8_100_ascii(bh: &mut BenchHarness) {
-
- let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
- Lorem ipsum dolor sit amet, consectetur. ");
-
- assert_eq!(100, s.len());
- bh.iter(|| {
- let _ = is_utf8(s);
- });
- }
-
- #[bench]
- fn is_utf8_100_multibyte(bh: &mut BenchHarness) {
- let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
- assert_eq!(100, s.len());
- bh.iter(|| {
- let _ = is_utf8(s);
- });
- }
-
- #[bench]
- fn bench_with_capacity(bh: &mut BenchHarness) {
- bh.iter(|| {
- let _ = with_capacity(100);
- });
- }
-
- #[bench]
- fn bench_push_str(bh: &mut BenchHarness) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- bh.iter(|| {
- let mut r = ~"";
- r.push_str(s);
- });
- }
-
- #[bench]
- fn bench_connect(bh: &mut BenchHarness) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let sep = "→";
- let v = [s, s, s, s, s, s, s, s, s, s];
- bh.iter(|| {
- assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
- })
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
- * Task management.
- *
- * An executing Rust program consists of a tree of tasks, each with their own
- * stack, and sole ownership of their allocated heap data. Tasks communicate
- * with each other using ports and channels (see std::rt::comm for more info
- * about how communication works).
- *
- * Tasks can be spawned in 3 different modes.
- *
- * * Bidirectionally linked: This is the default mode and it's what ```spawn``` does.
- * Failures will be propagated from parent to child and vice versa.
- *
- * * Unidirectionally linked (parent->child): This type of task can be created with
- * ```spawn_supervised```. In this case, failures are propagated from parent to child
- * but not the other way around.
- *
- * * Unlinked: Tasks can be completely unlinked. These tasks can be created by using
- * ```spawn_unlinked```. In this case failures are not propagated at all.
- *
- * Tasks' failure modes can be further configured. For instance, parent tasks can (un)watch
- * children failures. Please, refer to TaskBuilder's documentation bellow for more information.
- *
- * When a (bi|uni)directionally linked task fails, its failure will be propagated to all tasks
- * linked to it, this will cause such tasks to fail by a `linked failure`.
- *
- * Task Scheduling:
- *
- * By default, every task is created in the same scheduler as its parent, where it
- * is scheduled cooperatively with all other tasks in that scheduler. Some specialized
- * applications may want more control over their scheduling, in which case they can be
- * spawned into a new scheduler with the specific properties required. See TaskBuilder's
- * documentation bellow for more information.
- *
- * # Example
- *
- * ```
- * do spawn {
- * log(error, "Hello, World!");
- * }
- * ```
- */
-
-#[allow(missing_doc)];
-
-use prelude::*;
-
-use cell::Cell;
-use comm::{stream, Chan, GenericChan, GenericPort, Port, Peekable};
-use result::{Result, Ok, Err};
-use rt::in_green_task_context;
-use rt::local::Local;
-use rt::task::{UnwindResult, Success, Failure};
-use send_str::{SendStr, IntoSendStr};
-use util;
-
-#[cfg(test)] use any::Any;
-#[cfg(test)] use comm::SharedChan;
-#[cfg(test)] use ptr;
-#[cfg(test)] use result;
-
-pub mod spawn;
-
-/// Indicates the manner in which a task exited.
-///
-/// A task that completes without failing is considered to exit successfully.
-/// Supervised ancestors and linked siblings may yet fail after this task
-/// succeeds. Also note that in such a case, it may be nondeterministic whether
-/// linked failure or successful exit happen first.
-///
-/// If you wish for this result's delivery to block until all linked and/or
-/// children tasks complete, recommend using a result future.
-pub type TaskResult = Result<(), ~Any>;
-
-pub struct TaskResultPort {
- priv port: Port<UnwindResult>
-}
-
-fn to_task_result(res: UnwindResult) -> TaskResult {
- match res {
- Success => Ok(()), Failure(a) => Err(a),
- }
-}
-
-impl GenericPort<TaskResult> for TaskResultPort {
- #[inline]
- fn recv(&self) -> TaskResult {
- to_task_result(self.port.recv())
- }
-
- #[inline]
- fn try_recv(&self) -> Option<TaskResult> {
- self.port.try_recv().map(to_task_result)
- }
-}
-
-impl Peekable<TaskResult> for TaskResultPort {
- #[inline]
- fn peek(&self) -> bool { self.port.peek() }
-}
-
-/// Scheduler modes
-#[deriving(Eq)]
-pub enum SchedMode {
- /// Run task on the default scheduler
- DefaultScheduler,
- /// All tasks run in the same OS thread
- SingleThreaded,
-}
-
-/**
- * Scheduler configuration options
- *
- * # Fields
- *
- * * sched_mode - The operating mode of the scheduler
- *
- */
-pub struct SchedOpts {
- priv mode: SchedMode,
-}
-
-/**
- * Task configuration options
- *
- * # Fields
- *
- * * watched - Make parent task collect exit status notifications from child
- * before reporting its own exit status. (This delays the parent
- * task's death and cleanup until after all transitively watched
- * children also exit.) True by default.
- *
- * * notify_chan - Enable lifecycle notifications on the given channel
- *
- * * name - A name for the task-to-be, for identification in failure messages.
- *
- * * sched - Specify the configuration of a new scheduler to create the task
- * in. This is of particular importance for libraries which want to call
- * into foreign code that blocks. Without doing so in a different
- * scheduler other tasks will be impeded or even blocked indefinitely.
- */
-pub struct TaskOpts {
- priv watched: bool,
- priv notify_chan: Option<Chan<UnwindResult>>,
- name: Option<SendStr>,
- sched: SchedOpts,
- stack_size: Option<uint>
-}
-
-/**
- * The task builder type.
- *
- * Provides detailed control over the properties and behavior of new tasks.
- */
-// NB: Builders are designed to be single-use because they do stateful
-// things that get weird when reusing - e.g. if you create a result future
-// it only applies to a single task, so then you have to maintain Some
-// potentially tricky state to ensure that everything behaves correctly
-// when you try to reuse the builder to spawn a new task. We'll just
-// sidestep that whole issue by making builders uncopyable and making
-// the run function move them in.
-pub struct TaskBuilder {
- opts: TaskOpts,
- priv gen_body: Option<proc(v: proc()) -> proc()>,
- priv can_not_copy: Option<util::NonCopyable>,
-}
-
-/**
- * Generate the base configuration for spawning a task, off of which more
- * configuration methods can be chained.
- * For example, task().unlinked().spawn is equivalent to spawn_unlinked.
- */
-pub fn task() -> TaskBuilder {
- TaskBuilder {
- opts: default_task_opts(),
- gen_body: None,
- can_not_copy: None,
- }
-}
-
-impl TaskBuilder {
- fn consume(mut self) -> TaskBuilder {
- let gen_body = self.gen_body.take();
- let notify_chan = self.opts.notify_chan.take();
- let name = self.opts.name.take();
- TaskBuilder {
- opts: TaskOpts {
- watched: self.opts.watched,
- notify_chan: notify_chan,
- name: name,
- sched: self.opts.sched,
- stack_size: self.opts.stack_size
- },
- gen_body: gen_body,
- can_not_copy: None,
- }
- }
-
- /// Cause the parent task to collect the child's exit status (and that of
- /// all transitively-watched grandchildren) before reporting its own.
- pub fn watched(&mut self) {
- self.opts.watched = true;
- }
-
- /// Allow the child task to outlive the parent task, at the possible cost
- /// of the parent reporting success even if the child task fails later.
- pub fn unwatched(&mut self) {
- self.opts.watched = false;
- }
-
- /// Get a future representing the exit status of the task.
- ///
- /// Taking the value of the future will block until the child task
- /// terminates. The future result return value will be created *before* the task is
- /// spawned; as such, do not invoke .get() on it directly;
- /// rather, store it in an outer variable/list for later use.
- ///
- /// Note that the future returned by this function is only useful for
- /// obtaining the value of the next task to be spawning with the
- /// builder. If additional tasks are spawned with the same builder
- /// then a new result future must be obtained prior to spawning each
- /// task.
- ///
- /// # Failure
- /// Fails if a future_result was already set for this task.
- pub fn future_result(&mut self) -> TaskResultPort {
- // FIXME (#3725): Once linked failure and notification are
- // handled in the library, I can imagine implementing this by just
- // registering an arbitrary number of task::on_exit handlers and
- // sending out messages.
-
- if self.opts.notify_chan.is_some() {
- fail!("Can't set multiple future_results for one task!");
- }
-
- // Construct the future and give it to the caller.
- let (notify_pipe_po, notify_pipe_ch) = stream::<UnwindResult>();
-
- // Reconfigure self to use a notify channel.
- self.opts.notify_chan = Some(notify_pipe_ch);
-
- TaskResultPort { port: notify_pipe_po }
- }
-
- /// Name the task-to-be. Currently the name is used for identification
- /// only in failure messages.
- pub fn name<S: IntoSendStr>(&mut self, name: S) {
- self.opts.name = Some(name.into_send_str());
- }
-
- /// Configure a custom scheduler mode for the task.
- pub fn sched_mode(&mut self, mode: SchedMode) {
- self.opts.sched.mode = mode;
- }
-
- /**
- * Add a wrapper to the body of the spawned task.
- *
- * Before the task is spawned it is passed through a 'body generator'
- * function that may perform local setup operations as well as wrap
- * the task body in remote setup operations. With this the behavior
- * of tasks can be extended in simple ways.
- *
- * This function augments the current body generator with a new body
- * generator by applying the task body which results from the
- * existing body generator to the new body generator.
- */
- pub fn add_wrapper(&mut self, wrapper: proc(v: proc()) -> proc()) {
- let prev_gen_body = self.gen_body.take();
- let prev_gen_body = match prev_gen_body {
- Some(gen) => gen,
- None => {
- let f: proc(proc()) -> proc() = proc(body) body;
- f
- }
- };
- let prev_gen_body = Cell::new(prev_gen_body);
- let next_gen_body = {
- let f: proc(proc()) -> proc() = proc(body) {
- let prev_gen_body = prev_gen_body.take();
- wrapper(prev_gen_body(body))
- };
- f
- };
- self.gen_body = Some(next_gen_body);
- }
-
- /**
- * Creates and executes a new child task
- *
- * Sets up a new task with its own call stack and schedules it to run
- * the provided unique closure. The task has the properties and behavior
- * specified by the task_builder.
- *
- * # Failure
- *
- * When spawning into a new scheduler, the number of threads requested
- * must be greater than zero.
- */
- pub fn spawn(mut self, f: proc()) {
- let gen_body = self.gen_body.take();
- let notify_chan = self.opts.notify_chan.take();
- let name = self.opts.name.take();
- let x = self.consume();
- let opts = TaskOpts {
- watched: x.opts.watched,
- notify_chan: notify_chan,
- name: name,
- sched: x.opts.sched,
- stack_size: x.opts.stack_size
- };
- let f = match gen_body {
- Some(gen) => {
- gen(f)
- }
- None => {
- f
- }
- };
- spawn::spawn_raw(opts, f);
- }
-
- /**
- * Execute a function in another task and return either the return value
- * of the function or result::err.
- *
- * # Return value
- *
- * If the function executed successfully then try returns result::ok
- * containing the value returned by the function. If the function fails
- * then try returns result::err containing nil.
- *
- * # Failure
- * Fails if a future_result was already set for this task.
- */
- pub fn try<T:Send>(mut self, f: proc() -> T) -> Result<T, ~Any> {
- let (po, ch) = stream::<T>();
-
- let result = self.future_result();
-
- do self.spawn {
- ch.send(f());
- }
-
- match result.recv() {
- Ok(()) => Ok(po.recv()),
- Err(cause) => Err(cause)
- }
- }
-}
-
-
-/* Task construction */
-
-pub fn default_task_opts() -> TaskOpts {
- /*!
- * The default task options
- *
- * By default all tasks are supervised by their parent, are spawned
- * into the same scheduler, and do not post lifecycle notifications.
- */
-
- TaskOpts {
- watched: true,
- notify_chan: None,
- name: None,
- sched: SchedOpts {
- mode: DefaultScheduler,
- },
- stack_size: None
- }
-}
-
-/* Spawn convenience functions */
-
-/// Creates and executes a new child task
-///
-/// Sets up a new task with its own call stack and schedules it to run
-/// the provided unique closure.
-///
-/// This function is equivalent to `task().spawn(f)`.
-pub fn spawn(f: proc()) {
- let task = task();
- task.spawn(f)
-}
-
-pub fn spawn_sched(mode: SchedMode, f: proc()) {
- /*!
- * Creates a new task on a new or existing scheduler.
- *
- * When there are no more tasks to execute the
- * scheduler terminates.
- *
- * # Failure
- *
- * In manual threads mode the number of threads requested must be
- * greater than zero.
- */
-
- let mut task = task();
- task.sched_mode(mode);
- task.spawn(f)
-}
-
-pub fn try<T:Send>(f: proc() -> T) -> Result<T, ~Any> {
- /*!
- * Execute a function in another task and return either the return value
- * of the function or result::err.
- *
- * This is equivalent to task().supervised().try.
- */
-
- let task = task();
- task.try(f)
-}
-
-
-/* Lifecycle functions */
-
-/// Read the name of the current task.
-pub fn with_task_name<U>(blk: |Option<&str>| -> U) -> U {
- use rt::task::Task;
-
- if in_green_task_context() {
- Local::borrow(|task: &mut Task| {
- match task.name {
- Some(ref name) => blk(Some(name.as_slice())),
- None => blk(None)
- }
- })
- } else {
- fail!("no task name exists in non-green task context")
- }
-}
-
-pub fn deschedule() {
- //! Yield control to the task scheduler
-
- use rt::local::Local;
- use rt::sched::Scheduler;
-
- // FIXME(#7544): Optimize this, since we know we won't block.
- let sched: ~Scheduler = Local::take();
- sched.yield_now();
-}
-
-pub fn failing() -> bool {
- //! True if the running task has failed
-
- use rt::task::Task;
-
- Local::borrow(|local: &mut Task| local.unwinder.unwinding)
-}
-
-// The following 8 tests test the following 2^3 combinations:
-// {un,}linked {un,}supervised failure propagation {up,down}wards.
-
-// !!! These tests are dangerous. If Something is buggy, they will hang, !!!
-// !!! instead of exiting cleanly. This might wedge the buildbots. !!!
-
-#[cfg(test)]
-fn block_forever() { let (po, _ch) = stream::<()>(); po.recv(); }
-
-#[test]
-fn test_unnamed_task() {
- use rt::test::run_in_uv_task;
-
- do run_in_uv_task {
- do spawn {
- with_task_name(|name| {
- assert!(name.is_none());
- })
- }
- }
-}
-
-#[test]
-fn test_owned_named_task() {
- use rt::test::run_in_uv_task;
-
- do run_in_uv_task {
- let mut t = task();
- t.name(~"ada lovelace");
- do t.spawn {
- with_task_name(|name| {
- assert!(name.unwrap() == "ada lovelace");
- })
- }
- }
-}
-
-#[test]
-fn test_static_named_task() {
- use rt::test::run_in_uv_task;
-
- do run_in_uv_task {
- let mut t = task();
- t.name("ada lovelace");
- do t.spawn {
- with_task_name(|name| {
- assert!(name.unwrap() == "ada lovelace");
- })
- }
- }
-}
-
-#[test]
-fn test_send_named_task() {
- use rt::test::run_in_uv_task;
-
- do run_in_uv_task {
- let mut t = task();
- t.name("ada lovelace".into_send_str());
- do t.spawn {
- with_task_name(|name| {
- assert!(name.unwrap() == "ada lovelace");
- })
- }
- }
-}
-
-#[test]
-fn test_run_basic() {
- let (po, ch) = stream::<()>();
- let builder = task();
- do builder.spawn {
- ch.send(());
- }
- po.recv();
-}
-
-#[cfg(test)]
-struct Wrapper {
- f: Option<Chan<()>>
-}
-
-#[test]
-fn test_add_wrapper() {
- let (po, ch) = stream::<()>();
- let mut b0 = task();
- let ch = Cell::new(ch);
- do b0.add_wrapper |body| {
- let ch = Cell::new(ch.take());
- let result: proc() = proc() {
- let ch = ch.take();
- body();
- ch.send(());
- };
- result
- };
- do b0.spawn { }
- po.recv();
-}
-
-#[test]
-fn test_future_result() {
- let mut builder = task();
- let result = builder.future_result();
- do builder.spawn {}
- assert!(result.recv().is_ok());
-
- let mut builder = task();
- let result = builder.future_result();
- do builder.spawn {
- fail!();
- }
- assert!(result.recv().is_err());
-}
-
-#[test] #[should_fail]
-fn test_back_to_the_future_result() {
- let mut builder = task();
- builder.future_result();
- builder.future_result();
-}
-
-#[test]
-fn test_try_success() {
- match do try {
- ~"Success!"
- } {
- result::Ok(~"Success!") => (),
- _ => fail!()
- }
-}
-
-#[test]
-fn test_try_fail() {
- match do try {
- fail!()
- } {
- result::Err(_) => (),
- result::Ok(()) => fail!()
- }
-}
-
-#[cfg(test)]
-fn get_sched_id() -> int {
- Local::borrow(|sched: &mut ::rt::sched::Scheduler| {
- sched.sched_id() as int
- })
-}
-
-#[test]
-fn test_spawn_sched() {
- let (po, ch) = stream::<()>();
- let ch = SharedChan::new(ch);
-
- fn f(i: int, ch: SharedChan<()>) {
- let parent_sched_id = get_sched_id();
-
- do spawn_sched(SingleThreaded) {
- let child_sched_id = get_sched_id();
- assert!(parent_sched_id != child_sched_id);
-
- if (i == 0) {
- ch.send(());
- } else {
- f(i - 1, ch.clone());
- }
- };
-
- }
- f(10, ch);
- po.recv();
-}
-
-#[test]
-fn test_spawn_sched_childs_on_default_sched() {
- let (po, ch) = stream();
-
- // Assuming tests run on the default scheduler
- let default_id = get_sched_id();
-
- let ch = Cell::new(ch);
- do spawn_sched(SingleThreaded) {
- let parent_sched_id = get_sched_id();
- let ch = Cell::new(ch.take());
- do spawn {
- let ch = ch.take();
- let child_sched_id = get_sched_id();
- assert!(parent_sched_id != child_sched_id);
- assert_eq!(child_sched_id, default_id);
- ch.send(());
- };
- };
-
- po.recv();
-}
-
-#[test]
-fn test_spawn_sched_blocking() {
- use unstable::mutex::Mutex;
-
- unsafe {
-
- // Testing that a task in one scheduler can block in foreign code
- // without affecting other schedulers
- 20u.times(|| {
- let (start_po, start_ch) = stream();
- let (fin_po, fin_ch) = stream();
-
- let mut lock = Mutex::new();
- let lock2 = Cell::new(lock.clone());
-
- do spawn_sched(SingleThreaded) {
- let mut lock = lock2.take();
- lock.lock();
-
- start_ch.send(());
-
- // Block the scheduler thread
- lock.wait();
- lock.unlock();
-
- fin_ch.send(());
- };
-
- // Wait until the other task has its lock
- start_po.recv();
-
- fn pingpong(po: &Port<int>, ch: &Chan<int>) {
- let mut val = 20;
- while val > 0 {
- val = po.recv();
- ch.send(val - 1);
- }
- }
-
- let (setup_po, setup_ch) = stream();
- let (parent_po, parent_ch) = stream();
- do spawn {
- let (child_po, child_ch) = stream();
- setup_ch.send(child_ch);
- pingpong(&child_po, &parent_ch);
- };
-
- let child_ch = setup_po.recv();
- child_ch.send(20);
- pingpong(&parent_po, &child_ch);
- lock.lock();
- lock.signal();
- lock.unlock();
- fin_po.recv();
- lock.destroy();
- })
- }
-}
-
-#[cfg(test)]
-fn avoid_copying_the_body(spawnfn: |v: proc()|) {
- let (p, ch) = stream::<uint>();
-
- let x = ~1;
- let x_in_parent = ptr::to_unsafe_ptr(&*x) as uint;
-
- do spawnfn || {
- let x_in_child = ptr::to_unsafe_ptr(&*x) as uint;
- ch.send(x_in_child);
- }
-
- let x_in_child = p.recv();
- assert_eq!(x_in_parent, x_in_child);
-}
-
-#[test]
-fn test_avoid_copying_the_body_spawn() {
- avoid_copying_the_body(spawn);
-}
-
-#[test]
-fn test_avoid_copying_the_body_task_spawn() {
- avoid_copying_the_body(|f| {
- let builder = task();
- do builder.spawn || {
- f();
- }
- })
-}
-
-#[test]
-fn test_avoid_copying_the_body_try() {
- avoid_copying_the_body(|f| {
- do try || {
- f()
- };
- })
-}
-
-#[test]
-fn test_child_doesnt_ref_parent() {
- // If the child refcounts the parent task, this will stack overflow when
- // climbing the task tree to dereference each ancestor. (See #1789)
- // (well, it would if the constant were 8000+ - I lowered it to be more
- // valgrind-friendly. try this at home, instead..!)
- static generations: uint = 16;
- fn child_no(x: uint) -> proc() {
- return proc() {
- if x < generations {
- let mut t = task();
- t.unwatched();
- t.spawn(child_no(x+1));
- }
- }
- }
- let mut t = task();
- t.unwatched();
- t.spawn(child_no(0));
-}
-
-#[test]
-fn test_simple_newsched_spawn() {
- use rt::test::run_in_uv_task;
-
- do run_in_uv_task {
- spawn(proc()())
- }
-}
-
-#[test]
-fn test_try_fail_message_static_str() {
- match do try {
- fail!("static string");
- } {
- Err(e) => {
- type T = &'static str;
- assert!(e.is::<T>());
- assert_eq!(*e.move::<T>().unwrap(), "static string");
- }
- Ok(()) => fail!()
- }
-}
-
-#[test]
-fn test_try_fail_message_owned_str() {
- match do try {
- fail!(~"owned string");
- } {
- Err(e) => {
- type T = ~str;
- assert!(e.is::<T>());
- assert_eq!(*e.move::<T>().unwrap(), ~"owned string");
- }
- Ok(()) => fail!()
- }
-}
-
-#[test]
-fn test_try_fail_message_any() {
- match do try {
- fail!(~413u16 as ~Any);
- } {
- Err(e) => {
- type T = ~Any;
- assert!(e.is::<T>());
- let any = e.move::<T>().unwrap();
- assert!(any.is::<u16>());
- assert_eq!(*any.move::<u16>().unwrap(), 413u16);
- }
- Ok(()) => fail!()
- }
-}
-
-#[test]
-fn test_try_fail_message_unit_struct() {
- struct Juju;
-
- match do try {
- fail!(Juju)
- } {
- Err(ref e) if e.is::<Juju>() => {}
- Err(_) | Ok(()) => fail!()
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!**************************************************************************
- *
- * WARNING: linked failure has been removed since this doc comment was written,
- * but it was so pretty that I didn't want to remove it.
- *
- * Spawning & linked failure
- *
- * Several data structures are involved in task management to allow properly
- * propagating failure across linked/supervised tasks.
- *
- * (1) The "taskgroup_arc" is an unsafe::exclusive which contains a hashset of
- * all tasks that are part of the group. Some tasks are 'members', which
- * means if they fail, they will kill everybody else in the taskgroup.
- * Other tasks are 'descendants', which means they will not kill tasks
- * from this group, but can be killed by failing members.
- *
- * A new one of these is created each spawn_linked or spawn_supervised.
- *
- * (2) The "taskgroup" is a per-task control structure that tracks a task's
- * spawn configuration. It contains a reference to its taskgroup_arc, a
- * reference to its node in the ancestor list (below), and an optionally
- * configured notification port. These are stored in TLS.
- *
- * (3) The "ancestor_list" is a cons-style list of unsafe::exclusives which
- * tracks 'generations' of taskgroups -- a group's ancestors are groups
- * which (directly or transitively) spawn_supervised-ed them. Each task
- * is recorded in the 'descendants' of each of its ancestor groups.
- *
- * Spawning a supervised task is O(n) in the number of generations still
- * alive, and exiting (by success or failure) that task is also O(n).
- *
- * This diagram depicts the references between these data structures:
- *
- * linked_________________________________
- * ___/ _________ \___
- * / \ | group X | / \
- * ( A ) - - - - - - - > | {A,B} {}|< - - -( B )
- * \___/ |_________| \___/
- * unlinked
- * | __ (nil)
- * | //| The following code causes this:
- * |__ // /\ _________
- * / \ // || | group Y | fn taskA() {
- * ( C )- - - ||- - - > |{C} {D,E}| spawn(taskB);
- * \___/ / \=====> |_________| spawn_unlinked(taskC);
- * supervise /gen \ ...
- * | __ \ 00 / }
- * | //| \__/ fn taskB() { ... }
- * |__ // /\ _________ fn taskC() {
- * / \/ || | group Z | spawn_supervised(taskD);
- * ( D )- - - ||- - - > | {D} {E} | ...
- * \___/ / \=====> |_________| }
- * supervise /gen \ fn taskD() {
- * | __ \ 01 / spawn_supervised(taskE);
- * | //| \__/ ...
- * |__ // _________ }
- * / \/ | group W | fn taskE() { ... }
- * ( E )- - - - - - - > | {E} {} |
- * \___/ |_________|
- *
- * "tcb" "taskgroup_arc"
- * "ancestor_list"
- *
- ****************************************************************************/
-
-#[doc(hidden)];
-
-use prelude::*;
-
-use cell::Cell;
-use comm::{GenericChan, oneshot};
-use rt::local::Local;
-use rt::sched::{Scheduler, Shutdown, TaskFromFriend};
-use rt::task::{Task, Sched};
-use rt::task::UnwindResult;
-use rt::thread::Thread;
-use rt::work_queue::WorkQueue;
-use rt::{in_green_task_context, new_event_loop};
-use task::SingleThreaded;
-use task::TaskOpts;
-
-#[cfg(test)] use task::default_task_opts;
-#[cfg(test)] use comm;
-#[cfg(test)] use task;
-
-pub fn spawn_raw(mut opts: TaskOpts, f: proc()) {
- assert!(in_green_task_context());
-
- let mut task = if opts.sched.mode != SingleThreaded {
- if opts.watched {
- Task::build_child(opts.stack_size, f)
- } else {
- Task::build_root(opts.stack_size, f)
- }
- } else {
- unsafe {
- // Creating a 1:1 task:thread ...
- let sched: *mut Scheduler = Local::unsafe_borrow();
- let sched_handle = (*sched).make_handle();
-
- // Since this is a 1:1 scheduler we create a queue not in
- // the stealee set. The run_anything flag is set false
- // which will disable stealing.
- let work_queue = WorkQueue::new();
-
- // Create a new scheduler to hold the new task
- let mut new_sched = ~Scheduler::new_special(new_event_loop(),
- work_queue,
- (*sched).work_queues.clone(),
- (*sched).sleeper_list.clone(),
- false,
- Some(sched_handle));
- let mut new_sched_handle = new_sched.make_handle();
-
- // Allow the scheduler to exit when the pinned task exits
- new_sched_handle.send(Shutdown);
-
- // Pin the new task to the new scheduler
- let new_task = if opts.watched {
- Task::build_homed_child(opts.stack_size, f, Sched(new_sched_handle))
- } else {
- Task::build_homed_root(opts.stack_size, f, Sched(new_sched_handle))
- };
-
- // Create a task that will later be used to join with the new scheduler
- // thread when it is ready to terminate
- let (thread_port, thread_chan) = oneshot();
- let thread_port_cell = Cell::new(thread_port);
- let join_task = do Task::build_child(None) {
- debug!("running join task");
- let thread_port = thread_port_cell.take();
- let thread: Thread<()> = thread_port.recv();
- thread.join();
- };
-
- // Put the scheduler into another thread
- let new_sched_cell = Cell::new(new_sched);
- let orig_sched_handle_cell = Cell::new((*sched).make_handle());
- let join_task_cell = Cell::new(join_task);
-
- let thread = do Thread::start {
- let mut new_sched = new_sched_cell.take();
- let mut orig_sched_handle = orig_sched_handle_cell.take();
- let join_task = join_task_cell.take();
-
- let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool, None) || {
- debug!("boostrapping a 1:1 scheduler");
- };
- new_sched.bootstrap(bootstrap_task);
-
- // Now tell the original scheduler to join with this thread
- // by scheduling a thread-joining task on the original scheduler
- orig_sched_handle.send(TaskFromFriend(join_task));
-
- // NB: We can't simply send a message from here to another task
- // because this code isn't running in a task and message passing doesn't
- // work outside of tasks. Hence we're sending a scheduler message
- // to execute a new task directly to a scheduler.
- };
-
- // Give the thread handle to the join task
- thread_chan.send(thread);
-
- // When this task is enqueued on the current scheduler it will then get
- // forwarded to the scheduler to which it is pinned
- new_task
- }
- };
-
- if opts.notify_chan.is_some() {
- let notify_chan = opts.notify_chan.take_unwrap();
- let notify_chan = Cell::new(notify_chan);
- let on_exit: proc(UnwindResult) = proc(task_result) {
- notify_chan.take().send(task_result)
- };
- task.death.on_exit = Some(on_exit);
- }
-
- task.name = opts.name.take();
- debug!("spawn calling run_task");
- Scheduler::run_task(task);
-
-}
-
-#[test]
-fn test_spawn_raw_simple() {
- let (po, ch) = stream();
- do spawn_raw(default_task_opts()) {
- ch.send(());
- }
- po.recv();
-}
-
-#[test]
-fn test_spawn_raw_unsupervise() {
- let opts = task::TaskOpts {
- watched: false,
- notify_chan: None,
- .. default_task_opts()
- };
- do spawn_raw(opts) {
- fail!();
- }
-}
-
-#[test]
-fn test_spawn_raw_notify_success() {
- let (notify_po, notify_ch) = comm::stream();
-
- let opts = task::TaskOpts {
- notify_chan: Some(notify_ch),
- .. default_task_opts()
- };
- do spawn_raw(opts) {
- }
- assert!(notify_po.recv().is_success());
-}
-
-#[test]
-fn test_spawn_raw_notify_failure() {
- // New bindings for these
- let (notify_po, notify_ch) = comm::stream();
-
- let opts = task::TaskOpts {
- watched: false,
- notify_chan: Some(notify_ch),
- .. default_task_opts()
- };
- do spawn_raw(opts) {
- fail!();
- }
- assert!(notify_po.recv().is_failure());
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-The `ToBytes` and `IterBytes` traits
-
-*/
-
-use cast;
-use container::Container;
-use iter::Iterator;
-use option::{None, Option, Some};
-use rc::Rc;
-use str::{Str, StrSlice};
-use vec::{Vector, ImmutableVector};
-
-pub type Cb<'self> = 'self |buf: &[u8]| -> bool;
-
-///
-/// A trait to implement in order to make a type hashable;
-/// This works in combination with the trait `std::hash::Hash`, and
-/// may in the future be merged with that trait or otherwise
-/// modified when default methods and trait inheritance are
-/// completed.
-///
-/// IterBytes should be implemented so that the extent of the
-/// produced byte stream can be discovered, given the original
-/// type.
-/// For example, the IterBytes implementation for vectors emits
-/// its length first, and enums should emit their discriminant.
-///
-pub trait IterBytes {
- /// Call the provided callback `f` one or more times with
- /// byte-slices that should be used when computing a hash
- /// value or otherwise "flattening" the structure into
- /// a sequence of bytes. The `lsb0` parameter conveys
- /// whether the caller is asking for little-endian bytes
- /// (`true`) or big-endian (`false`); this should only be
- /// relevant in implementations that represent a single
- /// multi-byte datum such as a 32 bit integer or 64 bit
- /// floating-point value. It can be safely ignored for
- /// larger structured types as they are usually processed
- /// left-to-right in declaration order, regardless of
- /// underlying memory endianness.
- ///
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool;
-}
-
-impl IterBytes for bool {
- #[inline]
- fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
- f([
- *self as u8
- ])
- }
-}
-
-impl IterBytes for u8 {
- #[inline]
- fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
- f([
- *self
- ])
- }
-}
-
-impl IterBytes for u16 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- if lsb0 {
- f([
- *self as u8,
- (*self >> 8) as u8
- ])
- } else {
- f([
- (*self >> 8) as u8,
- *self as u8
- ])
- }
- }
-}
-
-impl IterBytes for u32 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- if lsb0 {
- f([
- *self as u8,
- (*self >> 8) as u8,
- (*self >> 16) as u8,
- (*self >> 24) as u8,
- ])
- } else {
- f([
- (*self >> 24) as u8,
- (*self >> 16) as u8,
- (*self >> 8) as u8,
- *self as u8
- ])
- }
- }
-}
-
-impl IterBytes for u64 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- if lsb0 {
- f([
- *self as u8,
- (*self >> 8) as u8,
- (*self >> 16) as u8,
- (*self >> 24) as u8,
- (*self >> 32) as u8,
- (*self >> 40) as u8,
- (*self >> 48) as u8,
- (*self >> 56) as u8
- ])
- } else {
- f([
- (*self >> 56) as u8,
- (*self >> 48) as u8,
- (*self >> 40) as u8,
- (*self >> 32) as u8,
- (*self >> 24) as u8,
- (*self >> 16) as u8,
- (*self >> 8) as u8,
- *self as u8
- ])
- }
- }
-}
-
-impl IterBytes for i8 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u8).iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for i16 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u16).iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for i32 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u32).iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for i64 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u64).iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for char {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u32).iter_bytes(lsb0, f)
- }
-}
-
-#[cfg(target_word_size = "32")]
-impl IterBytes for uint {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u32).iter_bytes(lsb0, f)
- }
-}
-
-#[cfg(target_word_size = "64")]
-impl IterBytes for uint {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as u64).iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for int {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as uint).iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for f32 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- let i: u32 = unsafe {
- // 0.0 == -0.0 so they should also have the same hashcode
- cast::transmute(if *self == -0.0 { 0.0 } else { *self })
- };
- i.iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for f64 {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- let i: u64 = unsafe {
- // 0.0 == -0.0 so they should also have the same hashcode
- cast::transmute(if *self == -0.0 { 0.0 } else { *self })
- };
- i.iter_bytes(lsb0, f)
- }
-}
-
-impl<'self,A:IterBytes> IterBytes for &'self [A] {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.len().iter_bytes(lsb0, |b| f(b)) &&
- self.iter().advance(|elt| elt.iter_bytes(lsb0, |b| f(b)))
- }
-}
-
-impl<A: IterBytes> IterBytes for (A, ) {
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- match *self {
- (ref a, ) => a.iter_bytes(lsb0, |b| f(b))
- }
- }
-}
-
-macro_rules! iter_bytes_tuple(
- ($($A:ident),+) => (
- impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- match *self {
- ($(ref $A),+) => {
- $(
- $A .iter_bytes(lsb0, |b| f(b))
- )&&+
- }
- }
- }
- }
- )
-)
-
-iter_bytes_tuple!(A, B)
-iter_bytes_tuple!(A, B, C)
-iter_bytes_tuple!(A, B, C, D)
-iter_bytes_tuple!(A, B, C, D, E)
-iter_bytes_tuple!(A, B, C, D, E, F)
-iter_bytes_tuple!(A, B, C, D, E, F, G)
-iter_bytes_tuple!(A, B, C, D, E, F, G, H)
-
-impl<A:IterBytes> IterBytes for ~[A] {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.as_slice().iter_bytes(lsb0, f)
- }
-}
-
-impl<A:IterBytes> IterBytes for @[A] {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.as_slice().iter_bytes(lsb0, f)
- }
-}
-
-impl<'self> IterBytes for &'self str {
- #[inline]
- fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
- // Terminate the string with a byte that does not appear in UTF-8
- f(self.as_bytes()) && f([0xFF])
- }
-}
-
-impl IterBytes for ~str {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.as_slice().iter_bytes(lsb0, f)
- }
-}
-
-impl IterBytes for @str {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.as_slice().iter_bytes(lsb0, f)
- }
-}
-
-impl<A:IterBytes> IterBytes for Option<A> {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- match *self {
- Some(ref a) => 0u8.iter_bytes(lsb0, |b| f(b)) && a.iter_bytes(lsb0, |b| f(b)),
- None => 1u8.iter_bytes(lsb0, f)
- }
- }
-}
-
-impl<'self,A:IterBytes> IterBytes for &'self A {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (**self).iter_bytes(lsb0, f)
- }
-}
-
-impl<A:IterBytes> IterBytes for @A {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (**self).iter_bytes(lsb0, f)
- }
-}
-
-impl<A:IterBytes> IterBytes for @mut A {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (**self).iter_bytes(lsb0, f)
- }
-}
-
-impl<A:IterBytes> IterBytes for Rc<A> {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- self.borrow().iter_bytes(lsb0, f)
- }
-}
-
-impl<A:IterBytes> IterBytes for ~A {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (**self).iter_bytes(lsb0, f)
- }
-}
-
-// NB: raw-pointer IterBytes does _not_ dereference
-// to the target; it just gives you the pointer-bytes.
-impl<A> IterBytes for *A {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as uint).iter_bytes(lsb0, f)
- }
-}
-
-impl<A> IterBytes for *mut A {
- #[inline]
- fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
- (*self as uint).iter_bytes(lsb0, f)
- }
-}
-
-/// A trait for converting a value to a list of bytes.
-pub trait ToBytes {
- /// Converts the current value to a list of bytes. This is equivalent to
- /// invoking iter_bytes on a type and collecting all yielded values in an
- /// array
- fn to_bytes(&self, lsb0: bool) -> ~[u8];
-}
-
-impl<A:IterBytes> ToBytes for A {
- fn to_bytes(&self, lsb0: bool) -> ~[u8] {
- use io::mem;
- use io::Writer;
-
- mem::with_mem_writer(|wr| {
- self.iter_bytes(lsb0, |bytes| {
- wr.write(bytes);
- true
- });
- })
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- // just test to see if it compiles:
- #[test] fn iterbytes_compiles () {
- takes_iterbytes((3,4,5,false));
- }
- fn takes_iterbytes<T : IterBytes>(_x : T) {}
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-The `ToStr` trait for converting to strings
-
-*/
-
-use option::{Some, None};
-use str::OwnedStr;
-use hashmap::HashMap;
-use hashmap::HashSet;
-use hash::Hash;
-use iter::Iterator;
-use cmp::Eq;
-use vec::ImmutableVector;
-
-/// A generic trait for converting a value to a string
-pub trait ToStr {
- /// Converts the value of `self` to an owned string
- fn to_str(&self) -> ~str;
-}
-
-/// Trait for converting a type to a string, consuming it in the process.
-pub trait ToStrConsume {
- /// Consume and convert to a string.
- fn into_str(self) -> ~str;
-}
-
-impl ToStr for () {
- #[inline]
- fn to_str(&self) -> ~str { ~"()" }
-}
-
-impl<A:ToStr> ToStr for (A,) {
- #[inline]
- fn to_str(&self) -> ~str {
- match *self {
- (ref a,) => {
- format!("({},)", (*a).to_str())
- }
- }
- }
-}
-
-impl<A:ToStr+Hash+Eq, B:ToStr> ToStr for HashMap<A, B> {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"{";
- let mut first = true;
- for (key, value) in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(key.to_str());
- acc.push_str(": ");
- acc.push_str(value.to_str());
- }
- acc.push_char('}');
- acc
- }
-}
-
-impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"{";
- let mut first = true;
- for element in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(element.to_str());
- }
- acc.push_char('}');
- acc
- }
-}
-
-impl<A:ToStr,B:ToStr> ToStr for (A, B) {
- #[inline]
- fn to_str(&self) -> ~str {
- // FIXME(#4653): this causes an llvm assertion
- //let &(ref a, ref b) = self;
- match *self {
- (ref a, ref b) => {
- format!("({}, {})", (*a).to_str(), (*b).to_str())
- }
- }
- }
-}
-
-impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
- #[inline]
- fn to_str(&self) -> ~str {
- // FIXME(#4653): this causes an llvm assertion
- //let &(ref a, ref b, ref c) = self;
- match *self {
- (ref a, ref b, ref c) => {
- format!("({}, {}, {})",
- (*a).to_str(),
- (*b).to_str(),
- (*c).to_str()
- )
- }
- }
- }
-}
-
-impl<'self,A:ToStr> ToStr for &'self [A] {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"[";
- let mut first = true;
- for elt in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(elt.to_str());
- }
- acc.push_char(']');
- acc
- }
-}
-
-impl<A:ToStr> ToStr for ~[A] {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"[";
- let mut first = true;
- for elt in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(elt.to_str());
- }
- acc.push_char(']');
- acc
- }
-}
-
-impl<A:ToStr> ToStr for @[A] {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"[";
- let mut first = true;
- for elt in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(elt.to_str());
- }
- acc.push_char(']');
- acc
- }
-}
-
-#[cfg(test)]
-mod tests {
- use hashmap::HashMap;
- use hashmap::HashSet;
- use container::{MutableSet, MutableMap};
- use super::*;
-
- #[test]
- fn test_simple_types() {
- assert_eq!(1i.to_str(), ~"1");
- assert_eq!((-1i).to_str(), ~"-1");
- assert_eq!(200u.to_str(), ~"200");
- assert_eq!(2u8.to_str(), ~"2");
- assert_eq!(true.to_str(), ~"true");
- assert_eq!(false.to_str(), ~"false");
- assert_eq!(().to_str(), ~"()");
- assert_eq!((~"hi").to_str(), ~"hi");
- assert_eq!((@"hi").to_str(), ~"hi");
- }
-
- #[test]
- fn test_tuple_types() {
- assert_eq!((1, 2).to_str(), ~"(1, 2)");
- assert_eq!((~"a", ~"b", false).to_str(), ~"(a, b, false)");
- assert_eq!(((), ((), 100)).to_str(), ~"((), ((), 100))");
- }
-
- #[test]
- fn test_vectors() {
- let x: ~[int] = ~[];
- assert_eq!(x.to_str(), ~"[]");
- assert_eq!((~[1]).to_str(), ~"[1]");
- assert_eq!((~[1, 2, 3]).to_str(), ~"[1, 2, 3]");
- assert!((~[~[], ~[1], ~[1, 1]]).to_str() ==
- ~"[[], [1], [1, 1]]");
- }
-
- struct StructWithToStrWithoutEqOrHash {
- value: int
- }
-
- impl ToStr for StructWithToStrWithoutEqOrHash {
- fn to_str(&self) -> ~str {
- format!("s{}", self.value)
- }
- }
-
- #[test]
- fn test_hashmap() {
- let mut table: HashMap<int, StructWithToStrWithoutEqOrHash> = HashMap::new();
- let empty: HashMap<int, StructWithToStrWithoutEqOrHash> = HashMap::new();
-
- table.insert(3, StructWithToStrWithoutEqOrHash { value: 4 });
- table.insert(1, StructWithToStrWithoutEqOrHash { value: 2 });
-
- let table_str = table.to_str();
-
- assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
- assert_eq!(empty.to_str(), ~"{}");
- }
-
- #[test]
- fn test_hashset() {
- let mut set: HashSet<int> = HashSet::new();
- let empty_set: HashSet<int> = HashSet::new();
-
- set.insert(1);
- set.insert(2);
-
- let set_str = set.to_str();
-
- assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
- assert_eq!(empty_set.to_str(), ~"{}");
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! An ordered map and set for integer keys implemented as a radix trie
-
-use prelude::*;
-use uint;
-use util::{swap, replace};
-use vec;
-
-// FIXME: #5244: need to manually update the TrieNode constructor
-static SHIFT: uint = 4;
-static SIZE: uint = 1 << SHIFT;
-static MASK: uint = SIZE - 1;
-
-enum Child<T> {
- Internal(~TrieNode<T>),
- External(uint, T),
- Nothing
-}
-
-#[allow(missing_doc)]
-pub struct TrieMap<T> {
- priv root: TrieNode<T>,
- priv length: uint
-}
-
-impl<T> Container for TrieMap<T> {
- /// Return the number of elements in the map
- #[inline]
- fn len(&self) -> uint { self.length }
-}
-
-impl<T> Mutable for TrieMap<T> {
- /// Clear the map, removing all values.
- #[inline]
- fn clear(&mut self) {
- self.root = TrieNode::new();
- self.length = 0;
- }
-}
-
-impl<T> Map<uint, T> for TrieMap<T> {
- /// Return a reference to the value corresponding to the key
- #[inline]
- fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
- let mut node: &'a TrieNode<T> = &self.root;
- let mut idx = 0;
- loop {
- match node.children[chunk(*key, idx)] {
- Internal(ref x) => node = &**x,
- External(stored, ref value) => {
- if stored == *key {
- return Some(value)
- } else {
- return None
- }
- }
- Nothing => return None
- }
- idx += 1;
- }
- }
-}
-
-impl<T> MutableMap<uint, T> for TrieMap<T> {
- /// Return a mutable reference to the value corresponding to the key
- #[inline]
- fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
- find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
- }
-
- /// Insert a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise None is returned.
- fn swap(&mut self, key: uint, value: T) -> Option<T> {
- let ret = insert(&mut self.root.count,
- &mut self.root.children[chunk(key, 0)],
- key, value, 1);
- if ret.is_none() { self.length += 1 }
- ret
- }
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- fn pop(&mut self, key: &uint) -> Option<T> {
- let ret = remove(&mut self.root.count,
- &mut self.root.children[chunk(*key, 0)],
- *key, 1);
- if ret.is_some() { self.length -= 1 }
- ret
- }
-}
-
-impl<T> TrieMap<T> {
- /// Create an empty TrieMap
- #[inline]
- pub fn new() -> TrieMap<T> {
- TrieMap{root: TrieNode::new(), length: 0}
- }
-
- /// Visit all key-value pairs in reverse order
- #[inline]
- pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- self.root.each_reverse(f)
- }
-
- /// Visit all key-value pairs in order
- #[inline]
- pub fn each<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- self.root.each(f)
- }
-
- /// Visit all keys in order
- #[inline]
- pub fn each_key(&self, f: |&uint| -> bool) -> bool {
- self.each(|k, _| f(k))
- }
-
- /// Visit all values in order
- #[inline]
- pub fn each_value<'a>(&'a self, f: |&'a T| -> bool) -> bool {
- self.each(|_, v| f(v))
- }
-
- /// Iterate over the map and mutate the contained values
- #[inline]
- pub fn mutate_values(&mut self, f: |&uint, &mut T| -> bool) -> bool {
- self.root.mutate_values(f)
- }
-
- /// Visit all keys in reverse order
- #[inline]
- pub fn each_key_reverse(&self, f: |&uint| -> bool) -> bool {
- self.each_reverse(|k, _| f(k))
- }
-
- /// Visit all values in reverse order
- #[inline]
- pub fn each_value_reverse(&self, f: |&T| -> bool) -> bool {
- self.each_reverse(|_, v| f(v))
- }
-
- /// Get an iterator over the key-value pairs in the map
- pub fn iter<'a>(&'a self) -> TrieMapIterator<'a, T> {
- TrieMapIterator {
- stack: ~[self.root.children.iter()],
- remaining_min: self.length,
- remaining_max: self.length
- }
- }
-
- // If `upper` is true then returns upper_bound else returns lower_bound.
- #[inline]
- fn bound<'a>(&'a self, key: uint, upper: bool) -> TrieMapIterator<'a, T> {
- let mut node: &'a TrieNode<T> = &self.root;
- let mut idx = 0;
- let mut it = TrieMapIterator {
- stack: ~[],
- remaining_min: 0,
- remaining_max: self.length
- };
- loop {
- let children = &node.children;
- let child_id = chunk(key, idx);
- match children[child_id] {
- Internal(ref n) => {
- node = &**n;
- it.stack.push(children.slice_from(child_id + 1).iter());
- }
- External(stored, _) => {
- if stored < key || (upper && stored == key) {
- it.stack.push(children.slice_from(child_id + 1).iter());
- } else {
- it.stack.push(children.slice_from(child_id).iter());
- }
- return it;
- }
- Nothing => {
- it.stack.push(children.slice_from(child_id + 1).iter());
- return it
- }
- }
- idx += 1;
- }
- }
-
- /// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
- /// If all keys in the map are less than `key` an empty iterator is returned.
- pub fn lower_bound<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
- self.bound(key, false)
- }
-
- /// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
- /// If all keys in the map are not greater than `key` an empty iterator is returned.
- pub fn upper_bound<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
- self.bound(key, true)
- }
-}
-
-impl<T> FromIterator<(uint, T)> for TrieMap<T> {
- fn from_iterator<Iter: Iterator<(uint, T)>>(iter: &mut Iter) -> TrieMap<T> {
- let mut map = TrieMap::new();
- map.extend(iter);
- map
- }
-}
-
-impl<T> Extendable<(uint, T)> for TrieMap<T> {
- fn extend<Iter: Iterator<(uint, T)>>(&mut self, iter: &mut Iter) {
- for (k, v) in *iter {
- self.insert(k, v);
- }
- }
-}
-
-#[allow(missing_doc)]
-pub struct TrieSet {
- priv map: TrieMap<()>
-}
-
-impl Container for TrieSet {
- /// Return the number of elements in the set
- #[inline]
- fn len(&self) -> uint { self.map.len() }
-}
-
-impl Mutable for TrieSet {
- /// Clear the set, removing all values.
- #[inline]
- fn clear(&mut self) { self.map.clear() }
-}
-
-impl TrieSet {
- /// Create an empty TrieSet
- #[inline]
- pub fn new() -> TrieSet {
- TrieSet{map: TrieMap::new()}
- }
-
- /// Return true if the set contains a value
- #[inline]
- pub fn contains(&self, value: &uint) -> bool {
- self.map.contains_key(value)
- }
-
- /// Add a value to the set. Return true if the value was not already
- /// present in the set.
- #[inline]
- pub fn insert(&mut self, value: uint) -> bool {
- self.map.insert(value, ())
- }
-
- /// Remove a value from the set. Return true if the value was
- /// present in the set.
- #[inline]
- pub fn remove(&mut self, value: &uint) -> bool {
- self.map.remove(value)
- }
-
- /// Visit all values in order
- #[inline]
- pub fn each(&self, f: |&uint| -> bool) -> bool { self.map.each_key(f) }
-
- /// Visit all values in reverse order
- #[inline]
- pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
- self.map.each_key_reverse(f)
- }
-
- /// Get an iterator over the values in the set
- #[inline]
- pub fn iter<'a>(&'a self) -> TrieSetIterator<'a> {
- TrieSetIterator{iter: self.map.iter()}
- }
-
- /// Get an iterator pointing to the first value that is not less than `val`.
- /// If all values in the set are less than `val` an empty iterator is returned.
- pub fn lower_bound<'a>(&'a self, val: uint) -> TrieSetIterator<'a> {
- TrieSetIterator{iter: self.map.lower_bound(val)}
- }
-
- /// Get an iterator pointing to the first value that key is greater than `val`.
- /// If all values in the set are not greater than `val` an empty iterator is returned.
- pub fn upper_bound<'a>(&'a self, val: uint) -> TrieSetIterator<'a> {
- TrieSetIterator{iter: self.map.upper_bound(val)}
- }
-}
-
-impl FromIterator<uint> for TrieSet {
- fn from_iterator<Iter: Iterator<uint>>(iter: &mut Iter) -> TrieSet {
- let mut set = TrieSet::new();
- set.extend(iter);
- set
- }
-}
-
-impl Extendable<uint> for TrieSet {
- fn extend<Iter: Iterator<uint>>(&mut self, iter: &mut Iter) {
- for elem in *iter {
- self.insert(elem);
- }
- }
-}
-
-struct TrieNode<T> {
- count: uint,
- children: [Child<T>, ..SIZE]
-}
-
-impl<T> TrieNode<T> {
- #[inline]
- fn new() -> TrieNode<T> {
- // FIXME: #5244: [Nothing, ..SIZE] should be possible without implicit
- // copyability
- TrieNode{count: 0,
- children: [Nothing, Nothing, Nothing, Nothing,
- Nothing, Nothing, Nothing, Nothing,
- Nothing, Nothing, Nothing, Nothing,
- Nothing, Nothing, Nothing, Nothing]}
- }
-}
-
-impl<T> TrieNode<T> {
- fn each<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- for elt in self.children.iter() {
- match *elt {
- Internal(ref x) => if !x.each(|i,t| f(i,t)) { return false },
- External(k, ref v) => if !f(&k, v) { return false },
- Nothing => ()
- }
- }
- true
- }
-
- fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- for elt in self.children.rev_iter() {
- match *elt {
- Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false },
- External(k, ref v) => if !f(&k, v) { return false },
- Nothing => ()
- }
- }
- true
- }
-
- fn mutate_values<'a>(&'a mut self, f: |&uint, &mut T| -> bool) -> bool {
- for child in self.children.mut_iter() {
- match *child {
- Internal(ref mut x) => if !x.mutate_values(|i,t| f(i,t)) {
- return false
- },
- External(k, ref mut v) => if !f(&k, v) { return false },
- Nothing => ()
- }
- }
- true
- }
-}
-
-// if this was done via a trait, the key could be generic
-#[inline]
-fn chunk(n: uint, idx: uint) -> uint {
- let sh = uint::bits - (SHIFT * (idx + 1));
- (n >> sh) & MASK
-}
-
-fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> {
- match *child {
- External(stored, ref mut value) if stored == key => Some(value),
- External(..) => None,
- Internal(ref mut x) => find_mut(&mut x.children[chunk(key, idx)], key, idx + 1),
- Nothing => None
- }
-}
-
-fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
- idx: uint) -> Option<T> {
- let mut tmp = Nothing;
- let ret;
- swap(&mut tmp, child);
-
- *child = match tmp {
- External(stored_key, stored_value) => {
- if stored_key == key {
- ret = Some(stored_value);
- External(stored_key, value)
- } else {
- // conflict - split the node
- let mut new = ~TrieNode::new();
- insert(&mut new.count,
- &mut new.children[chunk(stored_key, idx)],
- stored_key, stored_value, idx + 1);
- ret = insert(&mut new.count, &mut new.children[chunk(key, idx)],
- key, value, idx + 1);
- Internal(new)
- }
- }
- Internal(x) => {
- let mut x = x;
- ret = insert(&mut x.count, &mut x.children[chunk(key, idx)], key,
- value, idx + 1);
- Internal(x)
- }
- Nothing => {
- *count += 1;
- ret = None;
- External(key, value)
- }
- };
- return ret;
-}
-
-fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
- idx: uint) -> Option<T> {
- let (ret, this) = match *child {
- External(stored, _) if stored == key => {
- match replace(child, Nothing) {
- External(_, value) => (Some(value), true),
- _ => fail!()
- }
- }
- External(..) => (None, false),
- Internal(ref mut x) => {
- let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
- key, idx + 1);
- (ret, x.count == 0)
- }
- Nothing => (None, false)
- };
-
- if this {
- *child = Nothing;
- *count -= 1;
- }
- return ret;
-}
-
-/// Forward iterator over a map
-pub struct TrieMapIterator<'self, T> {
- priv stack: ~[vec::VecIterator<'self, Child<T>>],
- priv remaining_min: uint,
- priv remaining_max: uint
-}
-
-impl<'self, T> Iterator<(uint, &'self T)> for TrieMapIterator<'self, T> {
- fn next(&mut self) -> Option<(uint, &'self T)> {
- while !self.stack.is_empty() {
- match self.stack[self.stack.len() - 1].next() {
- None => {
- self.stack.pop();
- }
- Some(ref child) => {
- match **child {
- Internal(ref node) => {
- self.stack.push(node.children.iter());
- }
- External(key, ref value) => {
- self.remaining_max -= 1;
- if self.remaining_min > 0 {
- self.remaining_min -= 1;
- }
- return Some((key, value));
- }
- Nothing => {}
- }
- }
- }
- }
- return None;
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.remaining_min, Some(self.remaining_max))
- }
-}
-
-/// Forward iterator over a set
-pub struct TrieSetIterator<'self> {
- priv iter: TrieMapIterator<'self, ()>
-}
-
-impl<'self> Iterator<uint> for TrieSetIterator<'self> {
- fn next(&mut self) -> Option<uint> {
- self.iter.next().map(|(key, _)| key)
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-#[cfg(test)]
-pub fn check_integrity<T>(trie: &TrieNode<T>) {
- assert!(trie.count != 0);
-
- let mut sum = 0;
-
- for x in trie.children.iter() {
- match *x {
- Nothing => (),
- Internal(ref y) => {
- check_integrity(&**y);
- sum += 1
- }
- External(_, _) => { sum += 1 }
- }
- }
-
- assert_eq!(sum, trie.count);
-}
-
-#[cfg(test)]
-mod test_map {
- use super::*;
- use prelude::*;
- use iter::range_step;
- use uint;
-
- #[test]
- fn test_find_mut() {
- let mut m = TrieMap::new();
- assert!(m.insert(1, 12));
- assert!(m.insert(2, 8));
- assert!(m.insert(5, 14));
- let new = 100;
- match m.find_mut(&5) {
- None => fail!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_find_mut_missing() {
- let mut m = TrieMap::new();
- assert!(m.find_mut(&0).is_none());
- assert!(m.insert(1, 12));
- assert!(m.find_mut(&0).is_none());
- assert!(m.insert(2, 8));
- assert!(m.find_mut(&0).is_none());
- }
-
- #[test]
- fn test_step() {
- let mut trie = TrieMap::new();
- let n = 300u;
-
- for x in range_step(1u, n, 2) {
- assert!(trie.insert(x, x + 1));
- assert!(trie.contains_key(&x));
- check_integrity(&trie.root);
- }
-
- for x in range_step(0u, n, 2) {
- assert!(!trie.contains_key(&x));
- assert!(trie.insert(x, x + 1));
- check_integrity(&trie.root);
- }
-
- for x in range(0u, n) {
- assert!(trie.contains_key(&x));
- assert!(!trie.insert(x, x + 1));
- check_integrity(&trie.root);
- }
-
- for x in range_step(1u, n, 2) {
- assert!(trie.remove(&x));
- assert!(!trie.contains_key(&x));
- check_integrity(&trie.root);
- }
-
- for x in range_step(0u, n, 2) {
- assert!(trie.contains_key(&x));
- assert!(!trie.insert(x, x + 1));
- check_integrity(&trie.root);
- }
- }
-
- #[test]
- fn test_each() {
- let mut m = TrieMap::new();
-
- assert!(m.insert(3, 6));
- assert!(m.insert(0, 0));
- assert!(m.insert(4, 8));
- assert!(m.insert(2, 4));
- assert!(m.insert(1, 2));
-
- let mut n = 0;
- m.each(|k, v| {
- assert_eq!(*k, n);
- assert_eq!(*v, n * 2);
- n += 1;
- true
- });
- }
-
- #[test]
- fn test_each_break() {
- let mut m = TrieMap::new();
-
- for x in range(uint::max_value - 10000, uint::max_value).invert() {
- m.insert(x, x / 2);
- }
-
- let mut n = uint::max_value - 10000;
- m.each(|k, v| {
- if n == uint::max_value - 5000 { false } else {
- assert!(n < uint::max_value - 5000);
-
- assert_eq!(*k, n);
- assert_eq!(*v, n / 2);
- n += 1;
- true
- }
- });
- }
-
- #[test]
- fn test_each_reverse() {
- let mut m = TrieMap::new();
-
- assert!(m.insert(3, 6));
- assert!(m.insert(0, 0));
- assert!(m.insert(4, 8));
- assert!(m.insert(2, 4));
- assert!(m.insert(1, 2));
-
- let mut n = 4;
- m.each_reverse(|k, v| {
- assert_eq!(*k, n);
- assert_eq!(*v, n * 2);
- n -= 1;
- true
- });
- }
-
- #[test]
- fn test_each_reverse_break() {
- let mut m = TrieMap::new();
-
- for x in range(uint::max_value - 10000, uint::max_value).invert() {
- m.insert(x, x / 2);
- }
-
- let mut n = uint::max_value - 1;
- m.each_reverse(|k, v| {
- if n == uint::max_value - 5000 { false } else {
- assert!(n > uint::max_value - 5000);
-
- assert_eq!(*k, n);
- assert_eq!(*v, n / 2);
- n -= 1;
- true
- }
- });
- }
-
- #[test]
- fn test_swap() {
- let mut m = TrieMap::new();
- assert_eq!(m.swap(1, 2), None);
- assert_eq!(m.swap(1, 3), Some(2));
- assert_eq!(m.swap(1, 4), Some(3));
- }
-
- #[test]
- fn test_pop() {
- let mut m = TrieMap::new();
- m.insert(1, 2);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: TrieMap<int> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-
- #[test]
- fn test_iteration() {
- let empty_map : TrieMap<uint> = TrieMap::new();
- assert_eq!(empty_map.iter().next(), None);
-
- let first = uint::max_value - 10000;
- let last = uint::max_value;
-
- let mut map = TrieMap::new();
- for x in range(first, last).invert() {
- map.insert(x, x / 2);
- }
-
- let mut i = 0;
- for (k, &v) in map.iter() {
- assert_eq!(k, first + i);
- assert_eq!(v, k / 2);
- i += 1;
- }
- assert_eq!(i, last - first);
- }
-
- #[test]
- fn test_bound() {
- let empty_map : TrieMap<uint> = TrieMap::new();
- assert_eq!(empty_map.lower_bound(0).next(), None);
- assert_eq!(empty_map.upper_bound(0).next(), None);
-
- let last = 999u;
- let step = 3u;
- let value = 42u;
-
- let mut map : TrieMap<uint> = TrieMap::new();
- for x in range_step(0u, last, step) {
- assert!(x % step == 0);
- map.insert(x, value);
- }
-
- for i in range(0u, last - step) {
- let mut lb = map.lower_bound(i);
- let mut ub = map.upper_bound(i);
- let next_key = i - i % step + step;
- let next_pair = (next_key, &value);
- if (i % step == 0) {
- assert_eq!(lb.next(), Some((i, &value)));
- } else {
- assert_eq!(lb.next(), Some(next_pair));
- }
- assert_eq!(ub.next(), Some(next_pair));
- }
-
- let mut lb = map.lower_bound(last - step);
- assert_eq!(lb.next(), Some((last - step, &value)));
- let mut ub = map.upper_bound(last - step);
- assert_eq!(ub.next(), None);
-
- for i in range(last - step + 1, last) {
- let mut lb = map.lower_bound(i);
- assert_eq!(lb.next(), None);
- let mut ub = map.upper_bound(i);
- assert_eq!(ub.next(), None);
- }
- }
-}
-
-#[cfg(test)]
-mod test_set {
- use super::*;
- use prelude::*;
- use uint;
-
- #[test]
- fn test_sane_chunk() {
- let x = 1;
- let y = 1 << (uint::bits - 1);
-
- let mut trie = TrieSet::new();
-
- assert!(trie.insert(x));
- assert!(trie.insert(y));
-
- assert_eq!(trie.len(), 2);
-
- let expected = [x, y];
-
- let mut i = 0;
-
- trie.each(|x| {
- assert_eq!(expected[i], *x);
- i += 1;
- true
- });
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[9u, 8, 7, 6, 5, 4, 3, 2, 1];
-
- let set: TrieSet = xs.iter().map(|&x| x).collect();
-
- for x in xs.iter() {
- assert!(set.contains(x));
- }
- }
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Operations on tuples
-
-#[allow(missing_doc)];
-
-use clone::Clone;
-
-pub use self::inner::*;
-
-/// Method extensions to pairs where both types satisfy the `Clone` bound
-pub trait CopyableTuple<T, U> {
- /// Return the first element of self
- fn first(&self) -> T;
- /// Return the second element of self
- fn second(&self) -> U;
- /// Return the results of swapping the two elements of self
- fn swap(&self) -> (U, T);
-}
-
-impl<T:Clone,U:Clone> CopyableTuple<T, U> for (T, U) {
- /// Return the first element of self
- #[inline]
- fn first(&self) -> T {
- match *self {
- (ref t, _) => (*t).clone(),
- }
- }
-
- /// Return the second element of self
- #[inline]
- fn second(&self) -> U {
- match *self {
- (_, ref u) => (*u).clone(),
- }
- }
-
- /// Return the results of swapping the two elements of self
- #[inline]
- fn swap(&self) -> (U, T) {
- match (*self).clone() {
- (t, u) => (u, t),
- }
- }
-}
-
-/// Method extensions for pairs where the types don't necessarily satisfy the
-/// `Clone` bound
-pub trait ImmutableTuple<T, U> {
- /// Return a reference to the first element of self
- fn first_ref<'a>(&'a self) -> &'a T;
- /// Return a reference to the second element of self
- fn second_ref<'a>(&'a self) -> &'a U;
-}
-
-impl<T, U> ImmutableTuple<T, U> for (T, U) {
- #[inline]
- fn first_ref<'a>(&'a self) -> &'a T {
- match *self {
- (ref t, _) => t,
- }
- }
- #[inline]
- fn second_ref<'a>(&'a self) -> &'a U {
- match *self {
- (_, ref u) => u,
- }
- }
-}
-
-// macro for implementing n-ary tuple functions and operations
-
-macro_rules! tuple_impls {
- ($(
- ($move_trait:ident, $immutable_trait:ident) {
- $(($get_fn:ident, $get_ref_fn:ident) -> $T:ident {
- $move_pattern:pat, $ref_pattern:pat => $ret:expr
- })+
- }
- )+) => {
- pub mod inner {
- use clone::Clone;
- #[cfg(not(test))] use cmp::*;
- #[cfg(not(test))] use default::Default;
- #[cfg(not(test))] use num::Zero;
-
- $(
- pub trait $move_trait<$($T),+> {
- $(fn $get_fn(self) -> $T;)+
- }
-
- impl<$($T),+> $move_trait<$($T),+> for ($($T,)+) {
- $(
- #[inline]
- fn $get_fn(self) -> $T {
- let $move_pattern = self;
- $ret
- }
- )+
- }
-
- pub trait $immutable_trait<$($T),+> {
- $(fn $get_ref_fn<'a>(&'a self) -> &'a $T;)+
- }
-
- impl<$($T),+> $immutable_trait<$($T),+> for ($($T,)+) {
- $(
- #[inline]
- fn $get_ref_fn<'a>(&'a self) -> &'a $T {
- let $ref_pattern = *self;
- $ret
- }
- )+
- }
-
- impl<$($T:Clone),+> Clone for ($($T,)+) {
- fn clone(&self) -> ($($T,)+) {
- ($(self.$get_ref_fn().clone(),)+)
- }
- }
-
- #[cfg(not(test))]
- impl<$($T:Eq),+> Eq for ($($T,)+) {
- #[inline]
- fn eq(&self, other: &($($T,)+)) -> bool {
- $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+
- }
- #[inline]
- fn ne(&self, other: &($($T,)+)) -> bool {
- $(*self.$get_ref_fn() != *other.$get_ref_fn())||+
- }
- }
-
- #[cfg(not(test))]
- impl<$($T:TotalEq),+> TotalEq for ($($T,)+) {
- #[inline]
- fn equals(&self, other: &($($T,)+)) -> bool {
- $(self.$get_ref_fn().equals(other.$get_ref_fn()))&&+
- }
- }
-
- #[cfg(not(test))]
- impl<$($T:Ord + Eq),+> Ord for ($($T,)+) {
- #[inline]
- fn lt(&self, other: &($($T,)+)) -> bool {
- lexical_ord!(lt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
- }
- #[inline]
- fn le(&self, other: &($($T,)+)) -> bool {
- lexical_ord!(le, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
- }
- #[inline]
- fn ge(&self, other: &($($T,)+)) -> bool {
- lexical_ord!(ge, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
- }
- #[inline]
- fn gt(&self, other: &($($T,)+)) -> bool {
- lexical_ord!(gt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
- }
- }
-
- #[cfg(not(test))]
- impl<$($T:TotalOrd),+> TotalOrd for ($($T,)+) {
- #[inline]
- fn cmp(&self, other: &($($T,)+)) -> Ordering {
- lexical_cmp!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
- }
- }
-
- #[cfg(not(test))]
- impl<$($T:Default),+> Default for ($($T,)+) {
- #[inline]
- fn default() -> ($($T,)+) {
- ($({ let x: $T = Default::default(); x},)+)
- }
- }
-
- #[cfg(not(test))]
- impl<$($T:Zero),+> Zero for ($($T,)+) {
- #[inline]
- fn zero() -> ($($T,)+) {
- ($({ let x: $T = Zero::zero(); x},)+)
- }
- #[inline]
- fn is_zero(&self) -> bool {
- $(self.$get_ref_fn().is_zero())&&+
- }
- }
- )+
- }
- }
-}
-
-// Constructs an expression that performs a lexical ordering using method $rel.
-// The values are interleaved, so the macro invocation for
-// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
-// a3, b3)` (and similarly for `lexical_cmp`)
-macro_rules! lexical_ord {
- ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
- if *$a != *$b { lexical_ord!($rel, $a, $b) }
- else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
- };
- ($rel: ident, $a:expr, $b:expr) => { (*$a) . $rel ($b) };
-}
-
-macro_rules! lexical_cmp {
- ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
- match ($a).cmp($b) {
- Equal => lexical_cmp!($($rest_a, $rest_b),+),
- ordering => ordering
- }
- };
- ($a:expr, $b:expr) => { ($a).cmp($b) };
-}
-
-
-tuple_impls! {
- (Tuple1, ImmutableTuple1) {
- (n0, n0_ref) -> A { (a,), (ref a,) => a }
- }
-
- (Tuple2, ImmutableTuple2) {
- (n0, n0_ref) -> A { (a,_), (ref a,_) => a }
- (n1, n1_ref) -> B { (_,b), (_,ref b) => b }
- }
-
- (Tuple3, ImmutableTuple3) {
- (n0, n0_ref) -> A { (a,_,_), (ref a,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_), (_,ref b,_) => b }
- (n2, n2_ref) -> C { (_,_,c), (_,_,ref c) => c }
- }
-
- (Tuple4, ImmutableTuple4) {
- (n0, n0_ref) -> A { (a,_,_,_), (ref a,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_), (_,ref b,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_), (_,_,ref c,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d), (_,_,_,ref d) => d }
- }
-
- (Tuple5, ImmutableTuple5) {
- (n0, n0_ref) -> A { (a,_,_,_,_), (ref a,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_), (_,ref b,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_), (_,_,ref c,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_), (_,_,_,ref d,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e), (_,_,_,_,ref e) => e }
- }
-
- (Tuple6, ImmutableTuple6) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_), (ref a,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_), (_,ref b,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_), (_,_,ref c,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_), (_,_,_,ref d,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_), (_,_,_,_,ref e,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f), (_,_,_,_,_,ref f) => f }
- }
-
- (Tuple7, ImmutableTuple7) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_,_), (ref a,_,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_,_), (_,ref b,_,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_,_), (_,_,ref c,_,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_,_), (_,_,_,ref d,_,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_,_), (_,_,_,_,ref e,_,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f,_), (_,_,_,_,_,ref f,_) => f }
- (n6, n6_ref) -> G { (_,_,_,_,_,_,g), (_,_,_,_,_,_,ref g) => g }
- }
-
- (Tuple8, ImmutableTuple8) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_), (_,_,ref c,_,_,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_), (_,_,_,ref d,_,_,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_), (_,_,_,_,ref e,_,_,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_), (_,_,_,_,_,ref f,_,_) => f }
- (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_), (_,_,_,_,_,_,ref g,_) => g }
- (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h), (_,_,_,_,_,_,_,ref h) => h }
- }
-
- (Tuple9, ImmutableTuple9) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_), (_,_,_,_,ref e,_,_,_,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_), (_,_,_,_,_,ref f,_,_,_) => f }
- (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_), (_,_,_,_,_,_,ref g,_,_) => g }
- (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_), (_,_,_,_,_,_,_,ref h,_) => h }
- (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i), (_,_,_,_,_,_,_,_,ref i) => i }
- }
-
- (Tuple10, ImmutableTuple10) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_) => f }
- (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_), (_,_,_,_,_,_,ref g,_,_,_) => g }
- (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_), (_,_,_,_,_,_,_,ref h,_,_) => h }
- (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_), (_,_,_,_,_,_,_,_,ref i,_) => i }
- (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j), (_,_,_,_,_,_,_,_,_,ref j) => j }
- }
-
- (Tuple11, ImmutableTuple11) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_,_) => f }
- (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_,_), (_,_,_,_,_,_,ref g,_,_,_,_) => g }
- (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_,_), (_,_,_,_,_,_,_,ref h,_,_,_) => h }
- (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_,_), (_,_,_,_,_,_,_,_,ref i,_,_) => i }
- (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j,_), (_,_,_,_,_,_,_,_,_,ref j,_) => j }
- (n10, n10_ref) -> K { (_,_,_,_,_,_,_,_,_,_,k), (_,_,_,_,_,_,_,_,_,_,ref k) => k }
- }
-
- (Tuple12, ImmutableTuple12) {
- (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_,_,_) => a }
- (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_,_,_) => b }
- (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_,_,_) => c }
- (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_,_,_) => d }
- (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_,_,_) => e }
- (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_,_,_) => f }
- (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_,_,_), (_,_,_,_,_,_,ref g,_,_,_,_,_) => g }
- (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_,_,_), (_,_,_,_,_,_,_,ref h,_,_,_,_) => h }
- (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_,_,_), (_,_,_,_,_,_,_,_,ref i,_,_,_) => i }
- (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j,_,_), (_,_,_,_,_,_,_,_,_,ref j,_,_) => j }
- (n10, n10_ref) -> K { (_,_,_,_,_,_,_,_,_,_,k,_), (_,_,_,_,_,_,_,_,_,_,ref k,_) => k }
- (n11, n11_ref) -> L { (_,_,_,_,_,_,_,_,_,_,_,l), (_,_,_,_,_,_,_,_,_,_,_,ref l) => l }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use clone::Clone;
- use cmp::*;
-
- #[test]
- fn test_tuple_ref() {
- let x = (~"foo", ~"bar");
- assert_eq!(x.first_ref(), &~"foo");
- assert_eq!(x.second_ref(), &~"bar");
- }
-
- #[test]
- fn test_tuple() {
- assert_eq!((948, 4039.48).first(), 948);
- assert_eq!((34.5, ~"foo").second(), ~"foo");
- assert_eq!(('a', 2).swap(), (2, 'a'));
- }
-
- #[test]
- fn test_clone() {
- let a = (1, ~"2");
- let b = a.clone();
- assert_eq!(a.first(), b.first());
- assert_eq!(a.second(), b.second());
- }
-
- #[test]
- fn test_n_tuple() {
- let t = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64);
- assert_eq!(t.n0(), 0u8);
- assert_eq!(t.n1(), 1u16);
- assert_eq!(t.n2(), 2u32);
- assert_eq!(t.n3(), 3u64);
- assert_eq!(t.n4(), 4u);
- assert_eq!(t.n5(), 5i8);
- assert_eq!(t.n6(), 6i16);
- assert_eq!(t.n7(), 7i32);
- assert_eq!(t.n8(), 8i64);
- assert_eq!(t.n9(), 9i);
- assert_eq!(t.n10(), 10f32);
- assert_eq!(t.n11(), 11f64);
-
- assert_eq!(t.n0_ref(), &0u8);
- assert_eq!(t.n1_ref(), &1u16);
- assert_eq!(t.n2_ref(), &2u32);
- assert_eq!(t.n3_ref(), &3u64);
- assert_eq!(t.n4_ref(), &4u);
- assert_eq!(t.n5_ref(), &5i8);
- assert_eq!(t.n6_ref(), &6i16);
- assert_eq!(t.n7_ref(), &7i32);
- assert_eq!(t.n8_ref(), &8i64);
- assert_eq!(t.n9_ref(), &9i);
- assert_eq!(t.n10_ref(), &10f32);
- assert_eq!(t.n11_ref(), &11f64);
- }
-
- #[test]
- fn test_tuple_cmp() {
- let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
-
- let nan = 0.0/0.0;
-
- // Eq
- assert_eq!(small, small);
- assert_eq!(big, big);
- assert!(small != big);
- assert!(big != small);
-
- // Ord
- assert!(small < big);
- assert!(!(small < small));
- assert!(!(big < small));
- assert!(!(big < big));
-
- assert!(small <= small);
- assert!(big <= big);
-
- assert!(big > small);
- assert!(small >= small);
- assert!(big >= small);
- assert!(big >= big);
-
- assert!(!((1.0, 2.0) < (nan, 3.0)));
- assert!(!((1.0, 2.0) <= (nan, 3.0)));
- assert!(!((1.0, 2.0) > (nan, 3.0)));
- assert!(!((1.0, 2.0) >= (nan, 3.0)));
- assert!(((1.0, 2.0) < (2.0, nan)));
- assert!(!((2.0, 2.0) < (2.0, nan)));
-
- // TotalEq
- assert!(small.equals(&small));
- assert!(big.equals(&big));
- assert!(!small.equals(&big));
- assert!(!big.equals(&small));
-
- // TotalOrd
- assert_eq!(small.cmp(&small), Equal);
- assert_eq!(big.cmp(&big), Equal);
- assert_eq!(small.cmp(&big), Less);
- assert_eq!(big.cmp(&small), Greater);
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// The following code was generated by "src/etc/unicode.py"
-
-#[allow(missing_doc)];
-#[allow(non_uppercase_statics)];
-
-pub mod general_category {
-
- fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
- use cmp::{Equal, Less, Greater};
- use vec::ImmutableVector;
- use option::None;
- r.bsearch(|&(lo,hi)| {
- if lo <= c && c <= hi { Equal }
- else if hi < c { Less }
- else { Greater }
- }) != None
- }
-
-
- static Cc_table : &'static [(char,char)] = &[
- ('\x00', '\x1f'), ('\x7f', '\x9f')
- ];
-
- pub fn Cc(c: char) -> bool {
- bsearch_range_table(c, Cc_table)
- }
-
- static Cf_table : &'static [(char,char)] = &[
- ('\xad', '\xad'), ('\u0600', '\u0604'),
- ('\u061c', '\u061c'), ('\u06dd', '\u06dd'),
- ('\u070f', '\u070f'), ('\u180e', '\u180e'),
- ('\u200b', '\u200f'), ('\u202a', '\u202e'),
- ('\u2060', '\u206f'), ('\ufeff', '\ufeff'),
- ('\ufff9', '\ufffb'), ('\U000110bd', '\U000110bd'),
- ('\U0001d173', '\U0001d17a'), ('\U000e0001', '\U000e007f')
- ];
-
- pub fn Cf(c: char) -> bool {
- bsearch_range_table(c, Cf_table)
- }
-
- static Co_table : &'static [(char,char)] = &[
- ('\ue000', '\uf8ff')
- ];
-
- pub fn Co(c: char) -> bool {
- bsearch_range_table(c, Co_table)
- }
-
- static Ll_table : &'static [(char,char)] = &[
- ('\x61', '\x7a'), ('\xb5', '\xb5'),
- ('\xdf', '\xf6'), ('\xf8', '\xff'),
- ('\u0101', '\u0101'), ('\u0103', '\u0103'),
- ('\u0105', '\u0105'), ('\u0107', '\u0107'),
- ('\u0109', '\u0109'), ('\u010b', '\u010b'),
- ('\u010d', '\u010d'), ('\u010f', '\u010f'),
- ('\u0111', '\u0111'), ('\u0113', '\u0113'),
- ('\u0115', '\u0115'), ('\u0117', '\u0117'),
- ('\u0119', '\u0119'), ('\u011b', '\u011b'),
- ('\u011d', '\u011d'), ('\u011f', '\u011f'),
- ('\u0121', '\u0121'), ('\u0123', '\u0123'),
- ('\u0125', '\u0125'), ('\u0127', '\u0127'),
- ('\u0129', '\u0129'), ('\u012b', '\u012b'),
- ('\u012d', '\u012d'), ('\u012f', '\u012f'),
- ('\u0131', '\u0131'), ('\u0133', '\u0133'),
- ('\u0135', '\u0135'), ('\u0137', '\u0138'),
- ('\u013a', '\u013a'), ('\u013c', '\u013c'),
- ('\u013e', '\u013e'), ('\u0140', '\u0140'),
- ('\u0142', '\u0142'), ('\u0144', '\u0144'),
- ('\u0146', '\u0146'), ('\u0148', '\u0149'),
- ('\u014b', '\u014b'), ('\u014d', '\u014d'),
- ('\u014f', '\u014f'), ('\u0151', '\u0151'),
- ('\u0153', '\u0153'), ('\u0155', '\u0155'),
- ('\u0157', '\u0157'), ('\u0159', '\u0159'),
- ('\u015b', '\u015b'), ('\u015d', '\u015d'),
- ('\u015f', '\u015f'), ('\u0161', '\u0161'),
- ('\u0163', '\u0163'), ('\u0165', '\u0165'),
- ('\u0167', '\u0167'), ('\u0169', '\u0169'),
- ('\u016b', '\u016b'), ('\u016d', '\u016d'),
- ('\u016f', '\u016f'), ('\u0171', '\u0171'),
- ('\u0173', '\u0173'), ('\u0175', '\u0175'),
- ('\u0177', '\u0177'), ('\u017a', '\u017a'),
- ('\u017c', '\u017c'), ('\u017e', '\u0180'),
- ('\u0183', '\u0183'), ('\u0185', '\u0185'),
- ('\u0188', '\u0188'), ('\u018c', '\u018d'),
- ('\u0192', '\u0192'), ('\u0195', '\u0195'),
- ('\u0199', '\u019b'), ('\u019e', '\u019e'),
- ('\u01a1', '\u01a1'), ('\u01a3', '\u01a3'),
- ('\u01a5', '\u01a5'), ('\u01a8', '\u01a8'),
- ('\u01aa', '\u01ab'), ('\u01ad', '\u01ad'),
- ('\u01b0', '\u01b0'), ('\u01b4', '\u01b4'),
- ('\u01b6', '\u01b6'), ('\u01b9', '\u01ba'),
- ('\u01bd', '\u01bf'), ('\u01c6', '\u01c6'),
- ('\u01c9', '\u01c9'), ('\u01cc', '\u01cc'),
- ('\u01ce', '\u01ce'), ('\u01d0', '\u01d0'),
- ('\u01d2', '\u01d2'), ('\u01d4', '\u01d4'),
- ('\u01d6', '\u01d6'), ('\u01d8', '\u01d8'),
- ('\u01da', '\u01da'), ('\u01dc', '\u01dd'),
- ('\u01df', '\u01df'), ('\u01e1', '\u01e1'),
- ('\u01e3', '\u01e3'), ('\u01e5', '\u01e5'),
- ('\u01e7', '\u01e7'), ('\u01e9', '\u01e9'),
- ('\u01eb', '\u01eb'), ('\u01ed', '\u01ed'),
- ('\u01ef', '\u01f0'), ('\u01f3', '\u01f3'),
- ('\u01f5', '\u01f5'), ('\u01f9', '\u01f9'),
- ('\u01fb', '\u01fb'), ('\u01fd', '\u01fd'),
- ('\u01ff', '\u01ff'), ('\u0201', '\u0201'),
- ('\u0203', '\u0203'), ('\u0205', '\u0205'),
- ('\u0207', '\u0207'), ('\u0209', '\u0209'),
- ('\u020b', '\u020b'), ('\u020d', '\u020d'),
- ('\u020f', '\u020f'), ('\u0211', '\u0211'),
- ('\u0213', '\u0213'), ('\u0215', '\u0215'),
- ('\u0217', '\u0217'), ('\u0219', '\u0219'),
- ('\u021b', '\u021b'), ('\u021d', '\u021d'),
- ('\u021f', '\u021f'), ('\u0221', '\u0221'),
- ('\u0223', '\u0223'), ('\u0225', '\u0225'),
- ('\u0227', '\u0227'), ('\u0229', '\u0229'),
- ('\u022b', '\u022b'), ('\u022d', '\u022d'),
- ('\u022f', '\u022f'), ('\u0231', '\u0231'),
- ('\u0233', '\u0239'), ('\u023c', '\u023c'),
- ('\u023f', '\u0240'), ('\u0242', '\u0242'),
- ('\u0247', '\u0247'), ('\u0249', '\u0249'),
- ('\u024b', '\u024b'), ('\u024d', '\u024d'),
- ('\u024f', '\u0293'), ('\u0295', '\u02af'),
- ('\u0371', '\u0371'), ('\u0373', '\u0373'),
- ('\u0377', '\u0377'), ('\u037b', '\u037d'),
- ('\u0390', '\u0390'), ('\u03ac', '\u03ce'),
- ('\u03d0', '\u03d1'), ('\u03d5', '\u03d7'),
- ('\u03d9', '\u03d9'), ('\u03db', '\u03db'),
- ('\u03dd', '\u03dd'), ('\u03df', '\u03df'),
- ('\u03e1', '\u03e1'), ('\u03e3', '\u03e3'),
- ('\u03e5', '\u03e5'), ('\u03e7', '\u03e7'),
- ('\u03e9', '\u03e9'), ('\u03eb', '\u03eb'),
- ('\u03ed', '\u03ed'), ('\u03ef', '\u03f3'),
- ('\u03f5', '\u03f5'), ('\u03f8', '\u03f8'),
- ('\u03fb', '\u03fc'), ('\u0430', '\u045f'),
- ('\u0461', '\u0461'), ('\u0463', '\u0463'),
- ('\u0465', '\u0465'), ('\u0467', '\u0467'),
- ('\u0469', '\u0469'), ('\u046b', '\u046b'),
- ('\u046d', '\u046d'), ('\u046f', '\u046f'),
- ('\u0471', '\u0471'), ('\u0473', '\u0473'),
- ('\u0475', '\u0475'), ('\u0477', '\u0477'),
- ('\u0479', '\u0479'), ('\u047b', '\u047b'),
- ('\u047d', '\u047d'), ('\u047f', '\u047f'),
- ('\u0481', '\u0481'), ('\u048b', '\u048b'),
- ('\u048d', '\u048d'), ('\u048f', '\u048f'),
- ('\u0491', '\u0491'), ('\u0493', '\u0493'),
- ('\u0495', '\u0495'), ('\u0497', '\u0497'),
- ('\u0499', '\u0499'), ('\u049b', '\u049b'),
- ('\u049d', '\u049d'), ('\u049f', '\u049f'),
- ('\u04a1', '\u04a1'), ('\u04a3', '\u04a3'),
- ('\u04a5', '\u04a5'), ('\u04a7', '\u04a7'),
- ('\u04a9', '\u04a9'), ('\u04ab', '\u04ab'),
- ('\u04ad', '\u04ad'), ('\u04af', '\u04af'),
- ('\u04b1', '\u04b1'), ('\u04b3', '\u04b3'),
- ('\u04b5', '\u04b5'), ('\u04b7', '\u04b7'),
- ('\u04b9', '\u04b9'), ('\u04bb', '\u04bb'),
- ('\u04bd', '\u04bd'), ('\u04bf', '\u04bf'),
- ('\u04c2', '\u04c2'), ('\u04c4', '\u04c4'),
- ('\u04c6', '\u04c6'), ('\u04c8', '\u04c8'),
- ('\u04ca', '\u04ca'), ('\u04cc', '\u04cc'),
- ('\u04ce', '\u04cf'), ('\u04d1', '\u04d1'),
- ('\u04d3', '\u04d3'), ('\u04d5', '\u04d5'),
- ('\u04d7', '\u04d7'), ('\u04d9', '\u04d9'),
- ('\u04db', '\u04db'), ('\u04dd', '\u04dd'),
- ('\u04df', '\u04df'), ('\u04e1', '\u04e1'),
- ('\u04e3', '\u04e3'), ('\u04e5', '\u04e5'),
- ('\u04e7', '\u04e7'), ('\u04e9', '\u04e9'),
- ('\u04eb', '\u04eb'), ('\u04ed', '\u04ed'),
- ('\u04ef', '\u04ef'), ('\u04f1', '\u04f1'),
- ('\u04f3', '\u04f3'), ('\u04f5', '\u04f5'),
- ('\u04f7', '\u04f7'), ('\u04f9', '\u04f9'),
- ('\u04fb', '\u04fb'), ('\u04fd', '\u04fd'),
- ('\u04ff', '\u04ff'), ('\u0501', '\u0501'),
- ('\u0503', '\u0503'), ('\u0505', '\u0505'),
- ('\u0507', '\u0507'), ('\u0509', '\u0509'),
- ('\u050b', '\u050b'), ('\u050d', '\u050d'),
- ('\u050f', '\u050f'), ('\u0511', '\u0511'),
- ('\u0513', '\u0513'), ('\u0515', '\u0515'),
- ('\u0517', '\u0517'), ('\u0519', '\u0519'),
- ('\u051b', '\u051b'), ('\u051d', '\u051d'),
- ('\u051f', '\u051f'), ('\u0521', '\u0521'),
- ('\u0523', '\u0523'), ('\u0525', '\u0525'),
- ('\u0527', '\u0527'), ('\u0561', '\u0587'),
- ('\u1d00', '\u1d2b'), ('\u1d6b', '\u1d77'),
- ('\u1d79', '\u1d9a'), ('\u1e01', '\u1e01'),
- ('\u1e03', '\u1e03'), ('\u1e05', '\u1e05'),
- ('\u1e07', '\u1e07'), ('\u1e09', '\u1e09'),
- ('\u1e0b', '\u1e0b'), ('\u1e0d', '\u1e0d'),
- ('\u1e0f', '\u1e0f'), ('\u1e11', '\u1e11'),
- ('\u1e13', '\u1e13'), ('\u1e15', '\u1e15'),
- ('\u1e17', '\u1e17'), ('\u1e19', '\u1e19'),
- ('\u1e1b', '\u1e1b'), ('\u1e1d', '\u1e1d'),
- ('\u1e1f', '\u1e1f'), ('\u1e21', '\u1e21'),
- ('\u1e23', '\u1e23'), ('\u1e25', '\u1e25'),
- ('\u1e27', '\u1e27'), ('\u1e29', '\u1e29'),
- ('\u1e2b', '\u1e2b'), ('\u1e2d', '\u1e2d'),
- ('\u1e2f', '\u1e2f'), ('\u1e31', '\u1e31'),
- ('\u1e33', '\u1e33'), ('\u1e35', '\u1e35'),
- ('\u1e37', '\u1e37'), ('\u1e39', '\u1e39'),
- ('\u1e3b', '\u1e3b'), ('\u1e3d', '\u1e3d'),
- ('\u1e3f', '\u1e3f'), ('\u1e41', '\u1e41'),
- ('\u1e43', '\u1e43'), ('\u1e45', '\u1e45'),
- ('\u1e47', '\u1e47'), ('\u1e49', '\u1e49'),
- ('\u1e4b', '\u1e4b'), ('\u1e4d', '\u1e4d'),
- ('\u1e4f', '\u1e4f'), ('\u1e51', '\u1e51'),
- ('\u1e53', '\u1e53'), ('\u1e55', '\u1e55'),
- ('\u1e57', '\u1e57'), ('\u1e59', '\u1e59'),
- ('\u1e5b', '\u1e5b'), ('\u1e5d', '\u1e5d'),
- ('\u1e5f', '\u1e5f'), ('\u1e61', '\u1e61'),
- ('\u1e63', '\u1e63'), ('\u1e65', '\u1e65'),
- ('\u1e67', '\u1e67'), ('\u1e69', '\u1e69'),
- ('\u1e6b', '\u1e6b'), ('\u1e6d', '\u1e6d'),
- ('\u1e6f', '\u1e6f'), ('\u1e71', '\u1e71'),
- ('\u1e73', '\u1e73'), ('\u1e75', '\u1e75'),
- ('\u1e77', '\u1e77'), ('\u1e79', '\u1e79'),
- ('\u1e7b', '\u1e7b'), ('\u1e7d', '\u1e7d'),
- ('\u1e7f', '\u1e7f'), ('\u1e81', '\u1e81'),
- ('\u1e83', '\u1e83'), ('\u1e85', '\u1e85'),
- ('\u1e87', '\u1e87'), ('\u1e89', '\u1e89'),
- ('\u1e8b', '\u1e8b'), ('\u1e8d', '\u1e8d'),
- ('\u1e8f', '\u1e8f'), ('\u1e91', '\u1e91'),
- ('\u1e93', '\u1e93'), ('\u1e95', '\u1e9d'),
- ('\u1e9f', '\u1e9f'), ('\u1ea1', '\u1ea1'),
- ('\u1ea3', '\u1ea3'), ('\u1ea5', '\u1ea5'),
- ('\u1ea7', '\u1ea7'), ('\u1ea9', '\u1ea9'),
- ('\u1eab', '\u1eab'), ('\u1ead', '\u1ead'),
- ('\u1eaf', '\u1eaf'), ('\u1eb1', '\u1eb1'),
- ('\u1eb3', '\u1eb3'), ('\u1eb5', '\u1eb5'),
- ('\u1eb7', '\u1eb7'), ('\u1eb9', '\u1eb9'),
- ('\u1ebb', '\u1ebb'), ('\u1ebd', '\u1ebd'),
- ('\u1ebf', '\u1ebf'), ('\u1ec1', '\u1ec1'),
- ('\u1ec3', '\u1ec3'), ('\u1ec5', '\u1ec5'),
- ('\u1ec7', '\u1ec7'), ('\u1ec9', '\u1ec9'),
- ('\u1ecb', '\u1ecb'), ('\u1ecd', '\u1ecd'),
- ('\u1ecf', '\u1ecf'), ('\u1ed1', '\u1ed1'),
- ('\u1ed3', '\u1ed3'), ('\u1ed5', '\u1ed5'),
- ('\u1ed7', '\u1ed7'), ('\u1ed9', '\u1ed9'),
- ('\u1edb', '\u1edb'), ('\u1edd', '\u1edd'),
- ('\u1edf', '\u1edf'), ('\u1ee1', '\u1ee1'),
- ('\u1ee3', '\u1ee3'), ('\u1ee5', '\u1ee5'),
- ('\u1ee7', '\u1ee7'), ('\u1ee9', '\u1ee9'),
- ('\u1eeb', '\u1eeb'), ('\u1eed', '\u1eed'),
- ('\u1eef', '\u1eef'), ('\u1ef1', '\u1ef1'),
- ('\u1ef3', '\u1ef3'), ('\u1ef5', '\u1ef5'),
- ('\u1ef7', '\u1ef7'), ('\u1ef9', '\u1ef9'),
- ('\u1efb', '\u1efb'), ('\u1efd', '\u1efd'),
- ('\u1eff', '\u1f07'), ('\u1f10', '\u1f15'),
- ('\u1f20', '\u1f27'), ('\u1f30', '\u1f37'),
- ('\u1f40', '\u1f45'), ('\u1f50', '\u1f57'),
- ('\u1f60', '\u1f67'), ('\u1f70', '\u1f87'),
- ('\u1f90', '\u1f97'), ('\u1fa0', '\u1fa7'),
- ('\u1fb0', '\u1fb7'), ('\u1fbe', '\u1fbe'),
- ('\u1fc2', '\u1fc7'), ('\u1fd0', '\u1fd7'),
- ('\u1fe0', '\u1fe7'), ('\u1ff2', '\u1ff7'),
- ('\u210a', '\u210a'), ('\u210e', '\u210f'),
- ('\u2113', '\u2113'), ('\u212f', '\u212f'),
- ('\u2134', '\u2134'), ('\u2139', '\u2139'),
- ('\u213c', '\u213d'), ('\u2146', '\u2149'),
- ('\u214e', '\u214e'), ('\u2184', '\u2184'),
- ('\u2c30', '\u2c5e'), ('\u2c61', '\u2c61'),
- ('\u2c65', '\u2c66'), ('\u2c68', '\u2c68'),
- ('\u2c6a', '\u2c6a'), ('\u2c6c', '\u2c6c'),
- ('\u2c71', '\u2c71'), ('\u2c73', '\u2c74'),
- ('\u2c76', '\u2c7b'), ('\u2c81', '\u2c81'),
- ('\u2c83', '\u2c83'), ('\u2c85', '\u2c85'),
- ('\u2c87', '\u2c87'), ('\u2c89', '\u2c89'),
- ('\u2c8b', '\u2c8b'), ('\u2c8d', '\u2c8d'),
- ('\u2c8f', '\u2c8f'), ('\u2c91', '\u2c91'),
- ('\u2c93', '\u2c93'), ('\u2c95', '\u2c95'),
- ('\u2c97', '\u2c97'), ('\u2c99', '\u2c99'),
- ('\u2c9b', '\u2c9b'), ('\u2c9d', '\u2c9d'),
- ('\u2c9f', '\u2c9f'), ('\u2ca1', '\u2ca1'),
- ('\u2ca3', '\u2ca3'), ('\u2ca5', '\u2ca5'),
- ('\u2ca7', '\u2ca7'), ('\u2ca9', '\u2ca9'),
- ('\u2cab', '\u2cab'), ('\u2cad', '\u2cad'),
- ('\u2caf', '\u2caf'), ('\u2cb1', '\u2cb1'),
- ('\u2cb3', '\u2cb3'), ('\u2cb5', '\u2cb5'),
- ('\u2cb7', '\u2cb7'), ('\u2cb9', '\u2cb9'),
- ('\u2cbb', '\u2cbb'), ('\u2cbd', '\u2cbd'),
- ('\u2cbf', '\u2cbf'), ('\u2cc1', '\u2cc1'),
- ('\u2cc3', '\u2cc3'), ('\u2cc5', '\u2cc5'),
- ('\u2cc7', '\u2cc7'), ('\u2cc9', '\u2cc9'),
- ('\u2ccb', '\u2ccb'), ('\u2ccd', '\u2ccd'),
- ('\u2ccf', '\u2ccf'), ('\u2cd1', '\u2cd1'),
- ('\u2cd3', '\u2cd3'), ('\u2cd5', '\u2cd5'),
- ('\u2cd7', '\u2cd7'), ('\u2cd9', '\u2cd9'),
- ('\u2cdb', '\u2cdb'), ('\u2cdd', '\u2cdd'),
- ('\u2cdf', '\u2cdf'), ('\u2ce1', '\u2ce1'),
- ('\u2ce3', '\u2ce4'), ('\u2cec', '\u2cec'),
- ('\u2cee', '\u2cee'), ('\u2cf3', '\u2cf3'),
- ('\u2d00', '\u2d2d'), ('\ua641', '\ua641'),
- ('\ua643', '\ua643'), ('\ua645', '\ua645'),
- ('\ua647', '\ua647'), ('\ua649', '\ua649'),
- ('\ua64b', '\ua64b'), ('\ua64d', '\ua64d'),
- ('\ua64f', '\ua64f'), ('\ua651', '\ua651'),
- ('\ua653', '\ua653'), ('\ua655', '\ua655'),
- ('\ua657', '\ua657'), ('\ua659', '\ua659'),
- ('\ua65b', '\ua65b'), ('\ua65d', '\ua65d'),
- ('\ua65f', '\ua65f'), ('\ua661', '\ua661'),
- ('\ua663', '\ua663'), ('\ua665', '\ua665'),
- ('\ua667', '\ua667'), ('\ua669', '\ua669'),
- ('\ua66b', '\ua66b'), ('\ua66d', '\ua66d'),
- ('\ua681', '\ua681'), ('\ua683', '\ua683'),
- ('\ua685', '\ua685'), ('\ua687', '\ua687'),
- ('\ua689', '\ua689'), ('\ua68b', '\ua68b'),
- ('\ua68d', '\ua68d'), ('\ua68f', '\ua68f'),
- ('\ua691', '\ua691'), ('\ua693', '\ua693'),
- ('\ua695', '\ua695'), ('\ua697', '\ua697'),
- ('\ua723', '\ua723'), ('\ua725', '\ua725'),
- ('\ua727', '\ua727'), ('\ua729', '\ua729'),
- ('\ua72b', '\ua72b'), ('\ua72d', '\ua72d'),
- ('\ua72f', '\ua731'), ('\ua733', '\ua733'),
- ('\ua735', '\ua735'), ('\ua737', '\ua737'),
- ('\ua739', '\ua739'), ('\ua73b', '\ua73b'),
- ('\ua73d', '\ua73d'), ('\ua73f', '\ua73f'),
- ('\ua741', '\ua741'), ('\ua743', '\ua743'),
- ('\ua745', '\ua745'), ('\ua747', '\ua747'),
- ('\ua749', '\ua749'), ('\ua74b', '\ua74b'),
- ('\ua74d', '\ua74d'), ('\ua74f', '\ua74f'),
- ('\ua751', '\ua751'), ('\ua753', '\ua753'),
- ('\ua755', '\ua755'), ('\ua757', '\ua757'),
- ('\ua759', '\ua759'), ('\ua75b', '\ua75b'),
- ('\ua75d', '\ua75d'), ('\ua75f', '\ua75f'),
- ('\ua761', '\ua761'), ('\ua763', '\ua763'),
- ('\ua765', '\ua765'), ('\ua767', '\ua767'),
- ('\ua769', '\ua769'), ('\ua76b', '\ua76b'),
- ('\ua76d', '\ua76d'), ('\ua76f', '\ua76f'),
- ('\ua771', '\ua778'), ('\ua77a', '\ua77a'),
- ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'),
- ('\ua781', '\ua781'), ('\ua783', '\ua783'),
- ('\ua785', '\ua785'), ('\ua787', '\ua787'),
- ('\ua78c', '\ua78c'), ('\ua78e', '\ua78e'),
- ('\ua791', '\ua791'), ('\ua793', '\ua793'),
- ('\ua7a1', '\ua7a1'), ('\ua7a3', '\ua7a3'),
- ('\ua7a5', '\ua7a5'), ('\ua7a7', '\ua7a7'),
- ('\ua7a9', '\ua7a9'), ('\ua7fa', '\ua7fa'),
- ('\ufb00', '\ufb17'), ('\uff41', '\uff5a'),
- ('\U00010428', '\U0001044f'), ('\U0001d41a', '\U0001d433'),
- ('\U0001d44e', '\U0001d467'), ('\U0001d482', '\U0001d49b'),
- ('\U0001d4b6', '\U0001d4cf'), ('\U0001d4ea', '\U0001d503'),
- ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'),
- ('\U0001d586', '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'),
- ('\U0001d5ee', '\U0001d607'), ('\U0001d622', '\U0001d63b'),
- ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d71b'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d78f'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7c9'),
- ('\U0001d7cb', '\U0001d7cb')
- ];
-
- pub fn Ll(c: char) -> bool {
- bsearch_range_table(c, Ll_table)
- }
-
- static Lm_table : &'static [(char,char)] = &[
- ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
- ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
- ('\u02ee', '\u02ee'), ('\u0374', '\u0374'),
- ('\u037a', '\u037a'), ('\u0559', '\u0559'),
- ('\u0640', '\u0640'), ('\u06e5', '\u06e6'),
- ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
- ('\u081a', '\u081a'), ('\u0824', '\u0824'),
- ('\u0828', '\u0828'), ('\u0971', '\u0971'),
- ('\u0e46', '\u0e46'), ('\u0ec6', '\u0ec6'),
- ('\u10fc', '\u10fc'), ('\u17d7', '\u17d7'),
- ('\u1843', '\u1843'), ('\u1aa7', '\u1aa7'),
- ('\u1c78', '\u1c7d'), ('\u1d2c', '\u1d6a'),
- ('\u1d78', '\u1d78'), ('\u1d9b', '\u1dbf'),
- ('\u2071', '\u2071'), ('\u207f', '\u207f'),
- ('\u2090', '\u209c'), ('\u2c7c', '\u2c7d'),
- ('\u2d6f', '\u2d6f'), ('\u2e2f', '\u2e2f'),
- ('\u3005', '\u3005'), ('\u3031', '\u3035'),
- ('\u303b', '\u303b'), ('\u309d', '\u309e'),
- ('\u30fc', '\u30fe'), ('\ua015', '\ua015'),
- ('\ua4f8', '\ua4fd'), ('\ua60c', '\ua60c'),
- ('\ua67f', '\ua67f'), ('\ua717', '\ua71f'),
- ('\ua770', '\ua770'), ('\ua788', '\ua788'),
- ('\ua7f8', '\ua7f9'), ('\ua9cf', '\ua9cf'),
- ('\uaa70', '\uaa70'), ('\uaadd', '\uaadd'),
- ('\uaaf3', '\uaaf4'), ('\uff70', '\uff70'),
- ('\uff9e', '\uff9f'), ('\U00016f93', '\U00016f9f')
- ];
-
- pub fn Lm(c: char) -> bool {
- bsearch_range_table(c, Lm_table)
- }
-
- static Lo_table : &'static [(char,char)] = &[
- ('\xaa', '\xaa'), ('\xba', '\xba'),
- ('\u01bb', '\u01bb'), ('\u01c0', '\u01c3'),
- ('\u0294', '\u0294'), ('\u05d0', '\u05f2'),
- ('\u0620', '\u063f'), ('\u0641', '\u064a'),
- ('\u066e', '\u066f'), ('\u0671', '\u06d3'),
- ('\u06d5', '\u06d5'), ('\u06ee', '\u06ef'),
- ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'),
- ('\u0710', '\u0710'), ('\u0712', '\u072f'),
- ('\u074d', '\u07a5'), ('\u07b1', '\u07b1'),
- ('\u07ca', '\u07ea'), ('\u0800', '\u0815'),
- ('\u0840', '\u0858'), ('\u08a0', '\u08ac'),
- ('\u0904', '\u0939'), ('\u093d', '\u093d'),
- ('\u0950', '\u0950'), ('\u0958', '\u0961'),
- ('\u0972', '\u097f'), ('\u0985', '\u09b9'),
- ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'),
- ('\u09dc', '\u09e1'), ('\u09f0', '\u09f1'),
- ('\u0a05', '\u0a39'), ('\u0a59', '\u0a5e'),
- ('\u0a72', '\u0a74'), ('\u0a85', '\u0ab9'),
- ('\u0abd', '\u0abd'), ('\u0ad0', '\u0ae1'),
- ('\u0b05', '\u0b39'), ('\u0b3d', '\u0b3d'),
- ('\u0b5c', '\u0b61'), ('\u0b71', '\u0b71'),
- ('\u0b83', '\u0bb9'), ('\u0bd0', '\u0bd0'),
- ('\u0c05', '\u0c3d'), ('\u0c58', '\u0c61'),
- ('\u0c85', '\u0cb9'), ('\u0cbd', '\u0cbd'),
- ('\u0cde', '\u0ce1'), ('\u0cf1', '\u0cf2'),
- ('\u0d05', '\u0d3d'), ('\u0d4e', '\u0d4e'),
- ('\u0d60', '\u0d61'), ('\u0d7a', '\u0d7f'),
- ('\u0d85', '\u0dc6'), ('\u0e01', '\u0e30'),
- ('\u0e32', '\u0e33'), ('\u0e40', '\u0e45'),
- ('\u0e81', '\u0eb0'), ('\u0eb2', '\u0eb3'),
- ('\u0ebd', '\u0ec4'), ('\u0edc', '\u0f00'),
- ('\u0f40', '\u0f6c'), ('\u0f88', '\u0f8c'),
- ('\u1000', '\u102a'), ('\u103f', '\u103f'),
- ('\u1050', '\u1055'), ('\u105a', '\u105d'),
- ('\u1061', '\u1061'), ('\u1065', '\u1066'),
- ('\u106e', '\u1070'), ('\u1075', '\u1081'),
- ('\u108e', '\u108e'), ('\u10d0', '\u10fa'),
- ('\u10fd', '\u135a'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u1700', '\u1711'),
- ('\u1720', '\u1731'), ('\u1740', '\u1751'),
- ('\u1760', '\u1770'), ('\u1780', '\u17b3'),
- ('\u17dc', '\u17dc'), ('\u1820', '\u1842'),
- ('\u1844', '\u18a8'), ('\u18aa', '\u191c'),
- ('\u1950', '\u19ab'), ('\u19c1', '\u19c7'),
- ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'),
- ('\u1b05', '\u1b33'), ('\u1b45', '\u1b4b'),
- ('\u1b83', '\u1ba0'), ('\u1bae', '\u1baf'),
- ('\u1bba', '\u1be5'), ('\u1c00', '\u1c23'),
- ('\u1c4d', '\u1c4f'), ('\u1c5a', '\u1c77'),
- ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'),
- ('\u1cf5', '\u1cf6'), ('\u2135', '\u2138'),
- ('\u2d30', '\u2d67'), ('\u2d80', '\u2dde'),
- ('\u3006', '\u3006'), ('\u303c', '\u303c'),
- ('\u3041', '\u3096'), ('\u309f', '\u309f'),
- ('\u30a1', '\u30fa'), ('\u30ff', '\u318e'),
- ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
- ('\u3400', '\u4db5'), ('\u4e00', '\ua014'),
- ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
- ('\ua500', '\ua60b'), ('\ua610', '\ua61f'),
- ('\ua62a', '\ua62b'), ('\ua66e', '\ua66e'),
- ('\ua6a0', '\ua6e5'), ('\ua7fb', '\ua801'),
- ('\ua803', '\ua805'), ('\ua807', '\ua80a'),
- ('\ua80c', '\ua822'), ('\ua840', '\ua873'),
- ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
- ('\ua930', '\ua946'), ('\ua960', '\ua97c'),
- ('\ua984', '\ua9b2'), ('\uaa00', '\uaa28'),
- ('\uaa40', '\uaa42'), ('\uaa44', '\uaa4b'),
- ('\uaa60', '\uaa6f'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
- ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'),
- ('\uaab9', '\uaabd'), ('\uaac0', '\uaac0'),
- ('\uaac2', '\uaadc'), ('\uaae0', '\uaaea'),
- ('\uaaf2', '\uaaf2'), ('\uab01', '\uabe2'),
- ('\uac00', '\ud7fb'), ('\uf900', '\ufad9'),
- ('\ufb1d', '\ufb1d'), ('\ufb1f', '\ufb28'),
- ('\ufb2a', '\ufbb1'), ('\ufbd3', '\ufd3d'),
- ('\ufd50', '\ufdfb'), ('\ufe70', '\ufefc'),
- ('\uff66', '\uff6f'), ('\uff71', '\uff9d'),
- ('\uffa0', '\uffdc'), ('\U00010000', '\U000100fa'),
- ('\U00010280', '\U0001031e'), ('\U00010330', '\U00010340'),
- ('\U00010342', '\U00010349'), ('\U00010380', '\U0001039d'),
- ('\U000103a0', '\U000103cf'), ('\U00010450', '\U0001049d'),
- ('\U00010800', '\U00010855'), ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'), ('\U00010980', '\U00010a00'),
- ('\U00010a10', '\U00010a33'), ('\U00010a60', '\U00010a7c'),
- ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'),
- ('\U00010b60', '\U00010b72'), ('\U00010c00', '\U00010c48'),
- ('\U00011003', '\U00011037'), ('\U00011083', '\U000110af'),
- ('\U000110d0', '\U000110e8'), ('\U00011103', '\U00011126'),
- ('\U00011183', '\U000111b2'), ('\U000111c1', '\U000111c4'),
- ('\U00011680', '\U000116aa'), ('\U00012000', '\U0001236e'),
- ('\U00013000', '\U00016f50'), ('\U0001b000', '\U0001b001'),
- ('\U0001ee00', '\U0001eebb'), ('\U00020000', '\U0002fa1d')
- ];
-
- pub fn Lo(c: char) -> bool {
- bsearch_range_table(c, Lo_table)
- }
-
- static Lt_table : &'static [(char,char)] = &[
- ('\u01c5', '\u01c5'), ('\u01c8', '\u01c8'),
- ('\u01cb', '\u01cb'), ('\u01f2', '\u01f2'),
- ('\u1f88', '\u1f8f'), ('\u1f98', '\u1f9f'),
- ('\u1fa8', '\u1faf'), ('\u1fbc', '\u1fbc'),
- ('\u1fcc', '\u1fcc'), ('\u1ffc', '\u1ffc')
- ];
-
- pub fn Lt(c: char) -> bool {
- bsearch_range_table(c, Lt_table)
- }
-
- static Lu_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\xc0', '\xd6'),
- ('\xd8', '\xde'), ('\u0100', '\u0100'),
- ('\u0102', '\u0102'), ('\u0104', '\u0104'),
- ('\u0106', '\u0106'), ('\u0108', '\u0108'),
- ('\u010a', '\u010a'), ('\u010c', '\u010c'),
- ('\u010e', '\u010e'), ('\u0110', '\u0110'),
- ('\u0112', '\u0112'), ('\u0114', '\u0114'),
- ('\u0116', '\u0116'), ('\u0118', '\u0118'),
- ('\u011a', '\u011a'), ('\u011c', '\u011c'),
- ('\u011e', '\u011e'), ('\u0120', '\u0120'),
- ('\u0122', '\u0122'), ('\u0124', '\u0124'),
- ('\u0126', '\u0126'), ('\u0128', '\u0128'),
- ('\u012a', '\u012a'), ('\u012c', '\u012c'),
- ('\u012e', '\u012e'), ('\u0130', '\u0130'),
- ('\u0132', '\u0132'), ('\u0134', '\u0134'),
- ('\u0136', '\u0136'), ('\u0139', '\u0139'),
- ('\u013b', '\u013b'), ('\u013d', '\u013d'),
- ('\u013f', '\u013f'), ('\u0141', '\u0141'),
- ('\u0143', '\u0143'), ('\u0145', '\u0145'),
- ('\u0147', '\u0147'), ('\u014a', '\u014a'),
- ('\u014c', '\u014c'), ('\u014e', '\u014e'),
- ('\u0150', '\u0150'), ('\u0152', '\u0152'),
- ('\u0154', '\u0154'), ('\u0156', '\u0156'),
- ('\u0158', '\u0158'), ('\u015a', '\u015a'),
- ('\u015c', '\u015c'), ('\u015e', '\u015e'),
- ('\u0160', '\u0160'), ('\u0162', '\u0162'),
- ('\u0164', '\u0164'), ('\u0166', '\u0166'),
- ('\u0168', '\u0168'), ('\u016a', '\u016a'),
- ('\u016c', '\u016c'), ('\u016e', '\u016e'),
- ('\u0170', '\u0170'), ('\u0172', '\u0172'),
- ('\u0174', '\u0174'), ('\u0176', '\u0176'),
- ('\u0178', '\u0179'), ('\u017b', '\u017b'),
- ('\u017d', '\u017d'), ('\u0181', '\u0182'),
- ('\u0184', '\u0184'), ('\u0186', '\u0187'),
- ('\u0189', '\u018b'), ('\u018e', '\u0191'),
- ('\u0193', '\u0194'), ('\u0196', '\u0198'),
- ('\u019c', '\u019d'), ('\u019f', '\u01a0'),
- ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'),
- ('\u01a6', '\u01a7'), ('\u01a9', '\u01a9'),
- ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'),
- ('\u01b1', '\u01b3'), ('\u01b5', '\u01b5'),
- ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'),
- ('\u01c4', '\u01c4'), ('\u01c7', '\u01c7'),
- ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'),
- ('\u01cf', '\u01cf'), ('\u01d1', '\u01d1'),
- ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'),
- ('\u01d7', '\u01d7'), ('\u01d9', '\u01d9'),
- ('\u01db', '\u01db'), ('\u01de', '\u01de'),
- ('\u01e0', '\u01e0'), ('\u01e2', '\u01e2'),
- ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'),
- ('\u01e8', '\u01e8'), ('\u01ea', '\u01ea'),
- ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'),
- ('\u01f1', '\u01f1'), ('\u01f4', '\u01f4'),
- ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'),
- ('\u01fc', '\u01fc'), ('\u01fe', '\u01fe'),
- ('\u0200', '\u0200'), ('\u0202', '\u0202'),
- ('\u0204', '\u0204'), ('\u0206', '\u0206'),
- ('\u0208', '\u0208'), ('\u020a', '\u020a'),
- ('\u020c', '\u020c'), ('\u020e', '\u020e'),
- ('\u0210', '\u0210'), ('\u0212', '\u0212'),
- ('\u0214', '\u0214'), ('\u0216', '\u0216'),
- ('\u0218', '\u0218'), ('\u021a', '\u021a'),
- ('\u021c', '\u021c'), ('\u021e', '\u021e'),
- ('\u0220', '\u0220'), ('\u0222', '\u0222'),
- ('\u0224', '\u0224'), ('\u0226', '\u0226'),
- ('\u0228', '\u0228'), ('\u022a', '\u022a'),
- ('\u022c', '\u022c'), ('\u022e', '\u022e'),
- ('\u0230', '\u0230'), ('\u0232', '\u0232'),
- ('\u023a', '\u023b'), ('\u023d', '\u023e'),
- ('\u0241', '\u0241'), ('\u0243', '\u0246'),
- ('\u0248', '\u0248'), ('\u024a', '\u024a'),
- ('\u024c', '\u024c'), ('\u024e', '\u024e'),
- ('\u0370', '\u0370'), ('\u0372', '\u0372'),
- ('\u0376', '\u0376'), ('\u0386', '\u0386'),
- ('\u0388', '\u038f'), ('\u0391', '\u03ab'),
- ('\u03cf', '\u03cf'), ('\u03d2', '\u03d4'),
- ('\u03d8', '\u03d8'), ('\u03da', '\u03da'),
- ('\u03dc', '\u03dc'), ('\u03de', '\u03de'),
- ('\u03e0', '\u03e0'), ('\u03e2', '\u03e2'),
- ('\u03e4', '\u03e4'), ('\u03e6', '\u03e6'),
- ('\u03e8', '\u03e8'), ('\u03ea', '\u03ea'),
- ('\u03ec', '\u03ec'), ('\u03ee', '\u03ee'),
- ('\u03f4', '\u03f4'), ('\u03f7', '\u03f7'),
- ('\u03f9', '\u03fa'), ('\u03fd', '\u042f'),
- ('\u0460', '\u0460'), ('\u0462', '\u0462'),
- ('\u0464', '\u0464'), ('\u0466', '\u0466'),
- ('\u0468', '\u0468'), ('\u046a', '\u046a'),
- ('\u046c', '\u046c'), ('\u046e', '\u046e'),
- ('\u0470', '\u0470'), ('\u0472', '\u0472'),
- ('\u0474', '\u0474'), ('\u0476', '\u0476'),
- ('\u0478', '\u0478'), ('\u047a', '\u047a'),
- ('\u047c', '\u047c'), ('\u047e', '\u047e'),
- ('\u0480', '\u0480'), ('\u048a', '\u048a'),
- ('\u048c', '\u048c'), ('\u048e', '\u048e'),
- ('\u0490', '\u0490'), ('\u0492', '\u0492'),
- ('\u0494', '\u0494'), ('\u0496', '\u0496'),
- ('\u0498', '\u0498'), ('\u049a', '\u049a'),
- ('\u049c', '\u049c'), ('\u049e', '\u049e'),
- ('\u04a0', '\u04a0'), ('\u04a2', '\u04a2'),
- ('\u04a4', '\u04a4'), ('\u04a6', '\u04a6'),
- ('\u04a8', '\u04a8'), ('\u04aa', '\u04aa'),
- ('\u04ac', '\u04ac'), ('\u04ae', '\u04ae'),
- ('\u04b0', '\u04b0'), ('\u04b2', '\u04b2'),
- ('\u04b4', '\u04b4'), ('\u04b6', '\u04b6'),
- ('\u04b8', '\u04b8'), ('\u04ba', '\u04ba'),
- ('\u04bc', '\u04bc'), ('\u04be', '\u04be'),
- ('\u04c0', '\u04c1'), ('\u04c3', '\u04c3'),
- ('\u04c5', '\u04c5'), ('\u04c7', '\u04c7'),
- ('\u04c9', '\u04c9'), ('\u04cb', '\u04cb'),
- ('\u04cd', '\u04cd'), ('\u04d0', '\u04d0'),
- ('\u04d2', '\u04d2'), ('\u04d4', '\u04d4'),
- ('\u04d6', '\u04d6'), ('\u04d8', '\u04d8'),
- ('\u04da', '\u04da'), ('\u04dc', '\u04dc'),
- ('\u04de', '\u04de'), ('\u04e0', '\u04e0'),
- ('\u04e2', '\u04e2'), ('\u04e4', '\u04e4'),
- ('\u04e6', '\u04e6'), ('\u04e8', '\u04e8'),
- ('\u04ea', '\u04ea'), ('\u04ec', '\u04ec'),
- ('\u04ee', '\u04ee'), ('\u04f0', '\u04f0'),
- ('\u04f2', '\u04f2'), ('\u04f4', '\u04f4'),
- ('\u04f6', '\u04f6'), ('\u04f8', '\u04f8'),
- ('\u04fa', '\u04fa'), ('\u04fc', '\u04fc'),
- ('\u04fe', '\u04fe'), ('\u0500', '\u0500'),
- ('\u0502', '\u0502'), ('\u0504', '\u0504'),
- ('\u0506', '\u0506'), ('\u0508', '\u0508'),
- ('\u050a', '\u050a'), ('\u050c', '\u050c'),
- ('\u050e', '\u050e'), ('\u0510', '\u0510'),
- ('\u0512', '\u0512'), ('\u0514', '\u0514'),
- ('\u0516', '\u0516'), ('\u0518', '\u0518'),
- ('\u051a', '\u051a'), ('\u051c', '\u051c'),
- ('\u051e', '\u051e'), ('\u0520', '\u0520'),
- ('\u0522', '\u0522'), ('\u0524', '\u0524'),
- ('\u0526', '\u0526'), ('\u0531', '\u0556'),
- ('\u10a0', '\u10cd'), ('\u1e00', '\u1e00'),
- ('\u1e02', '\u1e02'), ('\u1e04', '\u1e04'),
- ('\u1e06', '\u1e06'), ('\u1e08', '\u1e08'),
- ('\u1e0a', '\u1e0a'), ('\u1e0c', '\u1e0c'),
- ('\u1e0e', '\u1e0e'), ('\u1e10', '\u1e10'),
- ('\u1e12', '\u1e12'), ('\u1e14', '\u1e14'),
- ('\u1e16', '\u1e16'), ('\u1e18', '\u1e18'),
- ('\u1e1a', '\u1e1a'), ('\u1e1c', '\u1e1c'),
- ('\u1e1e', '\u1e1e'), ('\u1e20', '\u1e20'),
- ('\u1e22', '\u1e22'), ('\u1e24', '\u1e24'),
- ('\u1e26', '\u1e26'), ('\u1e28', '\u1e28'),
- ('\u1e2a', '\u1e2a'), ('\u1e2c', '\u1e2c'),
- ('\u1e2e', '\u1e2e'), ('\u1e30', '\u1e30'),
- ('\u1e32', '\u1e32'), ('\u1e34', '\u1e34'),
- ('\u1e36', '\u1e36'), ('\u1e38', '\u1e38'),
- ('\u1e3a', '\u1e3a'), ('\u1e3c', '\u1e3c'),
- ('\u1e3e', '\u1e3e'), ('\u1e40', '\u1e40'),
- ('\u1e42', '\u1e42'), ('\u1e44', '\u1e44'),
- ('\u1e46', '\u1e46'), ('\u1e48', '\u1e48'),
- ('\u1e4a', '\u1e4a'), ('\u1e4c', '\u1e4c'),
- ('\u1e4e', '\u1e4e'), ('\u1e50', '\u1e50'),
- ('\u1e52', '\u1e52'), ('\u1e54', '\u1e54'),
- ('\u1e56', '\u1e56'), ('\u1e58', '\u1e58'),
- ('\u1e5a', '\u1e5a'), ('\u1e5c', '\u1e5c'),
- ('\u1e5e', '\u1e5e'), ('\u1e60', '\u1e60'),
- ('\u1e62', '\u1e62'), ('\u1e64', '\u1e64'),
- ('\u1e66', '\u1e66'), ('\u1e68', '\u1e68'),
- ('\u1e6a', '\u1e6a'), ('\u1e6c', '\u1e6c'),
- ('\u1e6e', '\u1e6e'), ('\u1e70', '\u1e70'),
- ('\u1e72', '\u1e72'), ('\u1e74', '\u1e74'),
- ('\u1e76', '\u1e76'), ('\u1e78', '\u1e78'),
- ('\u1e7a', '\u1e7a'), ('\u1e7c', '\u1e7c'),
- ('\u1e7e', '\u1e7e'), ('\u1e80', '\u1e80'),
- ('\u1e82', '\u1e82'), ('\u1e84', '\u1e84'),
- ('\u1e86', '\u1e86'), ('\u1e88', '\u1e88'),
- ('\u1e8a', '\u1e8a'), ('\u1e8c', '\u1e8c'),
- ('\u1e8e', '\u1e8e'), ('\u1e90', '\u1e90'),
- ('\u1e92', '\u1e92'), ('\u1e94', '\u1e94'),
- ('\u1e9e', '\u1e9e'), ('\u1ea0', '\u1ea0'),
- ('\u1ea2', '\u1ea2'), ('\u1ea4', '\u1ea4'),
- ('\u1ea6', '\u1ea6'), ('\u1ea8', '\u1ea8'),
- ('\u1eaa', '\u1eaa'), ('\u1eac', '\u1eac'),
- ('\u1eae', '\u1eae'), ('\u1eb0', '\u1eb0'),
- ('\u1eb2', '\u1eb2'), ('\u1eb4', '\u1eb4'),
- ('\u1eb6', '\u1eb6'), ('\u1eb8', '\u1eb8'),
- ('\u1eba', '\u1eba'), ('\u1ebc', '\u1ebc'),
- ('\u1ebe', '\u1ebe'), ('\u1ec0', '\u1ec0'),
- ('\u1ec2', '\u1ec2'), ('\u1ec4', '\u1ec4'),
- ('\u1ec6', '\u1ec6'), ('\u1ec8', '\u1ec8'),
- ('\u1eca', '\u1eca'), ('\u1ecc', '\u1ecc'),
- ('\u1ece', '\u1ece'), ('\u1ed0', '\u1ed0'),
- ('\u1ed2', '\u1ed2'), ('\u1ed4', '\u1ed4'),
- ('\u1ed6', '\u1ed6'), ('\u1ed8', '\u1ed8'),
- ('\u1eda', '\u1eda'), ('\u1edc', '\u1edc'),
- ('\u1ede', '\u1ede'), ('\u1ee0', '\u1ee0'),
- ('\u1ee2', '\u1ee2'), ('\u1ee4', '\u1ee4'),
- ('\u1ee6', '\u1ee6'), ('\u1ee8', '\u1ee8'),
- ('\u1eea', '\u1eea'), ('\u1eec', '\u1eec'),
- ('\u1eee', '\u1eee'), ('\u1ef0', '\u1ef0'),
- ('\u1ef2', '\u1ef2'), ('\u1ef4', '\u1ef4'),
- ('\u1ef6', '\u1ef6'), ('\u1ef8', '\u1ef8'),
- ('\u1efa', '\u1efa'), ('\u1efc', '\u1efc'),
- ('\u1efe', '\u1efe'), ('\u1f08', '\u1f0f'),
- ('\u1f18', '\u1f1d'), ('\u1f28', '\u1f2f'),
- ('\u1f38', '\u1f3f'), ('\u1f48', '\u1f4d'),
- ('\u1f59', '\u1f5f'), ('\u1f68', '\u1f6f'),
- ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'),
- ('\u1fd8', '\u1fdb'), ('\u1fe8', '\u1fec'),
- ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210b', '\u210d'),
- ('\u2110', '\u2112'), ('\u2115', '\u2115'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u2130', '\u2133'),
- ('\u213e', '\u213f'), ('\u2145', '\u2145'),
- ('\u2183', '\u2183'), ('\u2c00', '\u2c2e'),
- ('\u2c60', '\u2c60'), ('\u2c62', '\u2c64'),
- ('\u2c67', '\u2c67'), ('\u2c69', '\u2c69'),
- ('\u2c6b', '\u2c6b'), ('\u2c6d', '\u2c70'),
- ('\u2c72', '\u2c72'), ('\u2c75', '\u2c75'),
- ('\u2c7e', '\u2c80'), ('\u2c82', '\u2c82'),
- ('\u2c84', '\u2c84'), ('\u2c86', '\u2c86'),
- ('\u2c88', '\u2c88'), ('\u2c8a', '\u2c8a'),
- ('\u2c8c', '\u2c8c'), ('\u2c8e', '\u2c8e'),
- ('\u2c90', '\u2c90'), ('\u2c92', '\u2c92'),
- ('\u2c94', '\u2c94'), ('\u2c96', '\u2c96'),
- ('\u2c98', '\u2c98'), ('\u2c9a', '\u2c9a'),
- ('\u2c9c', '\u2c9c'), ('\u2c9e', '\u2c9e'),
- ('\u2ca0', '\u2ca0'), ('\u2ca2', '\u2ca2'),
- ('\u2ca4', '\u2ca4'), ('\u2ca6', '\u2ca6'),
- ('\u2ca8', '\u2ca8'), ('\u2caa', '\u2caa'),
- ('\u2cac', '\u2cac'), ('\u2cae', '\u2cae'),
- ('\u2cb0', '\u2cb0'), ('\u2cb2', '\u2cb2'),
- ('\u2cb4', '\u2cb4'), ('\u2cb6', '\u2cb6'),
- ('\u2cb8', '\u2cb8'), ('\u2cba', '\u2cba'),
- ('\u2cbc', '\u2cbc'), ('\u2cbe', '\u2cbe'),
- ('\u2cc0', '\u2cc0'), ('\u2cc2', '\u2cc2'),
- ('\u2cc4', '\u2cc4'), ('\u2cc6', '\u2cc6'),
- ('\u2cc8', '\u2cc8'), ('\u2cca', '\u2cca'),
- ('\u2ccc', '\u2ccc'), ('\u2cce', '\u2cce'),
- ('\u2cd0', '\u2cd0'), ('\u2cd2', '\u2cd2'),
- ('\u2cd4', '\u2cd4'), ('\u2cd6', '\u2cd6'),
- ('\u2cd8', '\u2cd8'), ('\u2cda', '\u2cda'),
- ('\u2cdc', '\u2cdc'), ('\u2cde', '\u2cde'),
- ('\u2ce0', '\u2ce0'), ('\u2ce2', '\u2ce2'),
- ('\u2ceb', '\u2ceb'), ('\u2ced', '\u2ced'),
- ('\u2cf2', '\u2cf2'), ('\ua640', '\ua640'),
- ('\ua642', '\ua642'), ('\ua644', '\ua644'),
- ('\ua646', '\ua646'), ('\ua648', '\ua648'),
- ('\ua64a', '\ua64a'), ('\ua64c', '\ua64c'),
- ('\ua64e', '\ua64e'), ('\ua650', '\ua650'),
- ('\ua652', '\ua652'), ('\ua654', '\ua654'),
- ('\ua656', '\ua656'), ('\ua658', '\ua658'),
- ('\ua65a', '\ua65a'), ('\ua65c', '\ua65c'),
- ('\ua65e', '\ua65e'), ('\ua660', '\ua660'),
- ('\ua662', '\ua662'), ('\ua664', '\ua664'),
- ('\ua666', '\ua666'), ('\ua668', '\ua668'),
- ('\ua66a', '\ua66a'), ('\ua66c', '\ua66c'),
- ('\ua680', '\ua680'), ('\ua682', '\ua682'),
- ('\ua684', '\ua684'), ('\ua686', '\ua686'),
- ('\ua688', '\ua688'), ('\ua68a', '\ua68a'),
- ('\ua68c', '\ua68c'), ('\ua68e', '\ua68e'),
- ('\ua690', '\ua690'), ('\ua692', '\ua692'),
- ('\ua694', '\ua694'), ('\ua696', '\ua696'),
- ('\ua722', '\ua722'), ('\ua724', '\ua724'),
- ('\ua726', '\ua726'), ('\ua728', '\ua728'),
- ('\ua72a', '\ua72a'), ('\ua72c', '\ua72c'),
- ('\ua72e', '\ua72e'), ('\ua732', '\ua732'),
- ('\ua734', '\ua734'), ('\ua736', '\ua736'),
- ('\ua738', '\ua738'), ('\ua73a', '\ua73a'),
- ('\ua73c', '\ua73c'), ('\ua73e', '\ua73e'),
- ('\ua740', '\ua740'), ('\ua742', '\ua742'),
- ('\ua744', '\ua744'), ('\ua746', '\ua746'),
- ('\ua748', '\ua748'), ('\ua74a', '\ua74a'),
- ('\ua74c', '\ua74c'), ('\ua74e', '\ua74e'),
- ('\ua750', '\ua750'), ('\ua752', '\ua752'),
- ('\ua754', '\ua754'), ('\ua756', '\ua756'),
- ('\ua758', '\ua758'), ('\ua75a', '\ua75a'),
- ('\ua75c', '\ua75c'), ('\ua75e', '\ua75e'),
- ('\ua760', '\ua760'), ('\ua762', '\ua762'),
- ('\ua764', '\ua764'), ('\ua766', '\ua766'),
- ('\ua768', '\ua768'), ('\ua76a', '\ua76a'),
- ('\ua76c', '\ua76c'), ('\ua76e', '\ua76e'),
- ('\ua779', '\ua779'), ('\ua77b', '\ua77b'),
- ('\ua77d', '\ua77e'), ('\ua780', '\ua780'),
- ('\ua782', '\ua782'), ('\ua784', '\ua784'),
- ('\ua786', '\ua786'), ('\ua78b', '\ua78b'),
- ('\ua78d', '\ua78d'), ('\ua790', '\ua790'),
- ('\ua792', '\ua792'), ('\ua7a0', '\ua7a0'),
- ('\ua7a2', '\ua7a2'), ('\ua7a4', '\ua7a4'),
- ('\ua7a6', '\ua7a6'), ('\ua7a8', '\ua7a8'),
- ('\ua7aa', '\ua7aa'), ('\uff21', '\uff3a'),
- ('\U00010400', '\U00010427'), ('\U0001d400', '\U0001d419'),
- ('\U0001d434', '\U0001d44d'), ('\U0001d468', '\U0001d481'),
- ('\U0001d49c', '\U0001d4b5'), ('\U0001d4d0', '\U0001d4e9'),
- ('\U0001d504', '\U0001d51c'), ('\U0001d538', '\U0001d550'),
- ('\U0001d56c', '\U0001d585'), ('\U0001d5a0', '\U0001d5b9'),
- ('\U0001d5d4', '\U0001d5ed'), ('\U0001d608', '\U0001d621'),
- ('\U0001d63c', '\U0001d655'), ('\U0001d670', '\U0001d689'),
- ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6e2', '\U0001d6fa'),
- ('\U0001d71c', '\U0001d734'), ('\U0001d756', '\U0001d76e'),
- ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca', '\U0001d7ca')
- ];
-
- pub fn Lu(c: char) -> bool {
- bsearch_range_table(c, Lu_table)
- }
-
- static Mc_table : &'static [(char,char)] = &[
- ('\u0903', '\u0903'), ('\u093b', '\u093b'),
- ('\u093e', '\u0940'), ('\u0949', '\u094c'),
- ('\u094e', '\u094f'), ('\u0982', '\u0983'),
- ('\u09be', '\u09c0'), ('\u09c7', '\u09cc'),
- ('\u09d7', '\u09d7'), ('\u0a03', '\u0a03'),
- ('\u0a3e', '\u0a40'), ('\u0a83', '\u0a83'),
- ('\u0abe', '\u0ac0'), ('\u0ac9', '\u0acc'),
- ('\u0b02', '\u0b03'), ('\u0b3e', '\u0b3e'),
- ('\u0b40', '\u0b40'), ('\u0b47', '\u0b4c'),
- ('\u0b57', '\u0b57'), ('\u0bbe', '\u0bbf'),
- ('\u0bc1', '\u0bcc'), ('\u0bd7', '\u0bd7'),
- ('\u0c01', '\u0c03'), ('\u0c41', '\u0c44'),
- ('\u0c82', '\u0c83'), ('\u0cbe', '\u0cbe'),
- ('\u0cc0', '\u0cc4'), ('\u0cc7', '\u0ccb'),
- ('\u0cd5', '\u0cd6'), ('\u0d02', '\u0d03'),
- ('\u0d3e', '\u0d40'), ('\u0d46', '\u0d4c'),
- ('\u0d57', '\u0d57'), ('\u0d82', '\u0d83'),
- ('\u0dcf', '\u0dd1'), ('\u0dd8', '\u0df3'),
- ('\u0f3e', '\u0f3f'), ('\u0f7f', '\u0f7f'),
- ('\u102b', '\u102c'), ('\u1031', '\u1031'),
- ('\u1038', '\u1038'), ('\u103b', '\u103c'),
- ('\u1056', '\u1057'), ('\u1062', '\u1064'),
- ('\u1067', '\u106d'), ('\u1083', '\u1084'),
- ('\u1087', '\u108c'), ('\u108f', '\u108f'),
- ('\u109a', '\u109c'), ('\u17b6', '\u17b6'),
- ('\u17be', '\u17c5'), ('\u17c7', '\u17c8'),
- ('\u1923', '\u1926'), ('\u1929', '\u1931'),
- ('\u1933', '\u1938'), ('\u19b0', '\u19c0'),
- ('\u19c8', '\u19c9'), ('\u1a19', '\u1a1a'),
- ('\u1a55', '\u1a55'), ('\u1a57', '\u1a57'),
- ('\u1a61', '\u1a61'), ('\u1a63', '\u1a64'),
- ('\u1a6d', '\u1a72'), ('\u1b04', '\u1b04'),
- ('\u1b35', '\u1b35'), ('\u1b3b', '\u1b3b'),
- ('\u1b3d', '\u1b41'), ('\u1b43', '\u1b44'),
- ('\u1b82', '\u1b82'), ('\u1ba1', '\u1ba1'),
- ('\u1ba6', '\u1ba7'), ('\u1baa', '\u1baa'),
- ('\u1bac', '\u1bad'), ('\u1be7', '\u1be7'),
- ('\u1bea', '\u1bec'), ('\u1bee', '\u1bee'),
- ('\u1bf2', '\u1bf3'), ('\u1c24', '\u1c2b'),
- ('\u1c34', '\u1c35'), ('\u1ce1', '\u1ce1'),
- ('\u1cf2', '\u1cf3'), ('\u302e', '\u302f'),
- ('\ua823', '\ua824'), ('\ua827', '\ua827'),
- ('\ua880', '\ua881'), ('\ua8b4', '\ua8c3'),
- ('\ua952', '\ua953'), ('\ua983', '\ua983'),
- ('\ua9b4', '\ua9b5'), ('\ua9ba', '\ua9bb'),
- ('\ua9bd', '\ua9c0'), ('\uaa2f', '\uaa30'),
- ('\uaa33', '\uaa34'), ('\uaa4d', '\uaa4d'),
- ('\uaa7b', '\uaa7b'), ('\uaaeb', '\uaaeb'),
- ('\uaaee', '\uaaef'), ('\uaaf5', '\uaaf5'),
- ('\uabe3', '\uabe4'), ('\uabe6', '\uabe7'),
- ('\uabe9', '\uabea'), ('\uabec', '\uabec'),
- ('\U00011000', '\U00011000'), ('\U00011002', '\U00011002'),
- ('\U00011082', '\U00011082'), ('\U000110b0', '\U000110b2'),
- ('\U000110b7', '\U000110b8'), ('\U0001112c', '\U0001112c'),
- ('\U00011182', '\U00011182'), ('\U000111b3', '\U000111b5'),
- ('\U000111bf', '\U000111c0'), ('\U000116ac', '\U000116ac'),
- ('\U000116ae', '\U000116af'), ('\U000116b6', '\U000116b6'),
- ('\U00016f51', '\U00016f7e'), ('\U0001d165', '\U0001d166'),
- ('\U0001d16d', '\U0001d172')
- ];
-
- pub fn Mc(c: char) -> bool {
- bsearch_range_table(c, Mc_table)
- }
-
- static Me_table : &'static [(char,char)] = &[
- ('\u0488', '\u0489'), ('\u20dd', '\u20e0'),
- ('\u20e2', '\u20e4'), ('\ua670', '\ua672')
- ];
-
- pub fn Me(c: char) -> bool {
- bsearch_range_table(c, Me_table)
- }
-
- static Mn_table : &'static [(char,char)] = &[
- ('\u0300', '\u036f'), ('\u0483', '\u0487'),
- ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
- ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'),
- ('\u05c7', '\u05c7'), ('\u0610', '\u061a'),
- ('\u064b', '\u065f'), ('\u0670', '\u0670'),
- ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
- ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'),
- ('\u0711', '\u0711'), ('\u0730', '\u074a'),
- ('\u07a6', '\u07b0'), ('\u07eb', '\u07f3'),
- ('\u0816', '\u0819'), ('\u081b', '\u0823'),
- ('\u0825', '\u0827'), ('\u0829', '\u082d'),
- ('\u0859', '\u085b'), ('\u08e4', '\u0902'),
- ('\u093a', '\u093a'), ('\u093c', '\u093c'),
- ('\u0941', '\u0948'), ('\u094d', '\u094d'),
- ('\u0951', '\u0957'), ('\u0962', '\u0963'),
- ('\u0981', '\u0981'), ('\u09bc', '\u09bc'),
- ('\u09c1', '\u09c4'), ('\u09cd', '\u09cd'),
- ('\u09e2', '\u09e3'), ('\u0a01', '\u0a02'),
- ('\u0a3c', '\u0a3c'), ('\u0a41', '\u0a51'),
- ('\u0a70', '\u0a71'), ('\u0a75', '\u0a82'),
- ('\u0abc', '\u0abc'), ('\u0ac1', '\u0ac8'),
- ('\u0acd', '\u0acd'), ('\u0ae2', '\u0ae3'),
- ('\u0b01', '\u0b01'), ('\u0b3c', '\u0b3c'),
- ('\u0b3f', '\u0b3f'), ('\u0b41', '\u0b44'),
- ('\u0b4d', '\u0b56'), ('\u0b62', '\u0b63'),
- ('\u0b82', '\u0b82'), ('\u0bc0', '\u0bc0'),
- ('\u0bcd', '\u0bcd'), ('\u0c3e', '\u0c40'),
- ('\u0c46', '\u0c56'), ('\u0c62', '\u0c63'),
- ('\u0cbc', '\u0cbc'), ('\u0cbf', '\u0cbf'),
- ('\u0cc6', '\u0cc6'), ('\u0ccc', '\u0ccd'),
- ('\u0ce2', '\u0ce3'), ('\u0d41', '\u0d44'),
- ('\u0d4d', '\u0d4d'), ('\u0d62', '\u0d63'),
- ('\u0dca', '\u0dca'), ('\u0dd2', '\u0dd6'),
- ('\u0e31', '\u0e31'), ('\u0e34', '\u0e3a'),
- ('\u0e47', '\u0e4e'), ('\u0eb1', '\u0eb1'),
- ('\u0eb4', '\u0ebc'), ('\u0ec8', '\u0ecd'),
- ('\u0f18', '\u0f19'), ('\u0f35', '\u0f35'),
- ('\u0f37', '\u0f37'), ('\u0f39', '\u0f39'),
- ('\u0f71', '\u0f7e'), ('\u0f80', '\u0f84'),
- ('\u0f86', '\u0f87'), ('\u0f8d', '\u0fbc'),
- ('\u0fc6', '\u0fc6'), ('\u102d', '\u1030'),
- ('\u1032', '\u1037'), ('\u1039', '\u103a'),
- ('\u103d', '\u103e'), ('\u1058', '\u1059'),
- ('\u105e', '\u1060'), ('\u1071', '\u1074'),
- ('\u1082', '\u1082'), ('\u1085', '\u1086'),
- ('\u108d', '\u108d'), ('\u109d', '\u109d'),
- ('\u135d', '\u135f'), ('\u1712', '\u1714'),
- ('\u1732', '\u1734'), ('\u1752', '\u1753'),
- ('\u1772', '\u1773'), ('\u17b4', '\u17b5'),
- ('\u17b7', '\u17bd'), ('\u17c6', '\u17c6'),
- ('\u17c9', '\u17d3'), ('\u17dd', '\u17dd'),
- ('\u180b', '\u180d'), ('\u18a9', '\u18a9'),
- ('\u1920', '\u1922'), ('\u1927', '\u1928'),
- ('\u1932', '\u1932'), ('\u1939', '\u193b'),
- ('\u1a17', '\u1a18'), ('\u1a1b', '\u1a1b'),
- ('\u1a56', '\u1a56'), ('\u1a58', '\u1a60'),
- ('\u1a62', '\u1a62'), ('\u1a65', '\u1a6c'),
- ('\u1a73', '\u1a7f'), ('\u1b00', '\u1b03'),
- ('\u1b34', '\u1b34'), ('\u1b36', '\u1b3a'),
- ('\u1b3c', '\u1b3c'), ('\u1b42', '\u1b42'),
- ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b81'),
- ('\u1ba2', '\u1ba5'), ('\u1ba8', '\u1ba9'),
- ('\u1bab', '\u1bab'), ('\u1be6', '\u1be6'),
- ('\u1be8', '\u1be9'), ('\u1bed', '\u1bed'),
- ('\u1bef', '\u1bf1'), ('\u1c2c', '\u1c33'),
- ('\u1c36', '\u1c37'), ('\u1cd0', '\u1cd2'),
- ('\u1cd4', '\u1ce0'), ('\u1ce2', '\u1ce8'),
- ('\u1ced', '\u1ced'), ('\u1cf4', '\u1cf4'),
- ('\u1dc0', '\u1dff'), ('\u20d0', '\u20dc'),
- ('\u20e1', '\u20e1'), ('\u20e5', '\u20f0'),
- ('\u2cef', '\u2cf1'), ('\u2d7f', '\u2d7f'),
- ('\u2de0', '\u2dff'), ('\u302a', '\u302d'),
- ('\u3099', '\u309a'), ('\ua66f', '\ua66f'),
- ('\ua674', '\ua67d'), ('\ua69f', '\ua69f'),
- ('\ua6f0', '\ua6f1'), ('\ua802', '\ua802'),
- ('\ua806', '\ua806'), ('\ua80b', '\ua80b'),
- ('\ua825', '\ua826'), ('\ua8c4', '\ua8c4'),
- ('\ua8e0', '\ua8f1'), ('\ua926', '\ua92d'),
- ('\ua947', '\ua951'), ('\ua980', '\ua982'),
- ('\ua9b3', '\ua9b3'), ('\ua9b6', '\ua9b9'),
- ('\ua9bc', '\ua9bc'), ('\uaa29', '\uaa2e'),
- ('\uaa31', '\uaa32'), ('\uaa35', '\uaa36'),
- ('\uaa43', '\uaa43'), ('\uaa4c', '\uaa4c'),
- ('\uaab0', '\uaab0'), ('\uaab2', '\uaab4'),
- ('\uaab7', '\uaab8'), ('\uaabe', '\uaabf'),
- ('\uaac1', '\uaac1'), ('\uaaec', '\uaaed'),
- ('\uaaf6', '\uaaf6'), ('\uabe5', '\uabe5'),
- ('\uabe8', '\uabe8'), ('\uabed', '\uabed'),
- ('\ufb1e', '\ufb1e'), ('\ufe00', '\ufe0f'),
- ('\ufe20', '\ufe26'), ('\U000101fd', '\U000101fd'),
- ('\U00010a01', '\U00010a0f'), ('\U00010a38', '\U00010a3f'),
- ('\U00011001', '\U00011001'), ('\U00011038', '\U00011046'),
- ('\U00011080', '\U00011081'), ('\U000110b3', '\U000110b6'),
- ('\U000110b9', '\U000110ba'), ('\U00011100', '\U00011102'),
- ('\U00011127', '\U0001112b'), ('\U0001112d', '\U00011134'),
- ('\U00011180', '\U00011181'), ('\U000111b6', '\U000111be'),
- ('\U000116ab', '\U000116ab'), ('\U000116ad', '\U000116ad'),
- ('\U000116b0', '\U000116b5'), ('\U000116b7', '\U000116b7'),
- ('\U00016f8f', '\U00016f92'), ('\U0001d167', '\U0001d169'),
- ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
- ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'),
- ('\U000e0100', '\U000e01ef')
- ];
-
- pub fn Mn(c: char) -> bool {
- bsearch_range_table(c, Mn_table)
- }
-
- static Nd_table : &'static [(char,char)] = &[
- ('\x30', '\x39'), ('\u0660', '\u0669'),
- ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
- ('\u0966', '\u096f'), ('\u09e6', '\u09ef'),
- ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
- ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'),
- ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
- ('\u0d66', '\u0d6f'), ('\u0e50', '\u0e59'),
- ('\u0ed0', '\u0ed9'), ('\u0f20', '\u0f29'),
- ('\u1040', '\u1049'), ('\u1090', '\u1099'),
- ('\u17e0', '\u17e9'), ('\u1810', '\u1819'),
- ('\u1946', '\u194f'), ('\u19d0', '\u19d9'),
- ('\u1a80', '\u1a99'), ('\u1b50', '\u1b59'),
- ('\u1bb0', '\u1bb9'), ('\u1c40', '\u1c49'),
- ('\u1c50', '\u1c59'), ('\ua620', '\ua629'),
- ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'),
- ('\ua9d0', '\ua9d9'), ('\uaa50', '\uaa59'),
- ('\uabf0', '\uabf9'), ('\uff10', '\uff19'),
- ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
- ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'),
- ('\U000111d0', '\U000111d9'), ('\U000116c0', '\U000116c9'),
- ('\U0001d7ce', '\U0001d7ff')
- ];
-
- pub fn Nd(c: char) -> bool {
- bsearch_range_table(c, Nd_table)
- }
-
- static Nl_table : &'static [(char,char)] = &[
- ('\u16ee', '\u16f0'), ('\u2160', '\u2182'),
- ('\u2185', '\u2188'), ('\u3007', '\u3007'),
- ('\u3021', '\u3029'), ('\u3038', '\u303a'),
- ('\ua6e6', '\ua6ef'), ('\U00010140', '\U00010174'),
- ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'),
- ('\U000103d1', '\U000103d5'), ('\U00012400', '\U00012462')
- ];
-
- pub fn Nl(c: char) -> bool {
- bsearch_range_table(c, Nl_table)
- }
-
- static No_table : &'static [(char,char)] = &[
- ('\xb2', '\xb3'), ('\xb9', '\xb9'),
- ('\xbc', '\xbe'), ('\u09f4', '\u09f9'),
- ('\u0b72', '\u0b77'), ('\u0bf0', '\u0bf2'),
- ('\u0c78', '\u0c7e'), ('\u0d70', '\u0d75'),
- ('\u0f2a', '\u0f33'), ('\u1369', '\u137c'),
- ('\u17f0', '\u17f9'), ('\u19da', '\u19da'),
- ('\u2070', '\u2070'), ('\u2074', '\u2079'),
- ('\u2080', '\u2089'), ('\u2150', '\u215f'),
- ('\u2189', '\u2189'), ('\u2460', '\u249b'),
- ('\u24ea', '\u24ff'), ('\u2776', '\u2793'),
- ('\u2cfd', '\u2cfd'), ('\u3192', '\u3195'),
- ('\u3220', '\u3229'), ('\u3248', '\u324f'),
- ('\u3251', '\u325f'), ('\u3280', '\u3289'),
- ('\u32b1', '\u32bf'), ('\ua830', '\ua835'),
- ('\U00010107', '\U00010133'), ('\U00010175', '\U00010178'),
- ('\U0001018a', '\U0001018a'), ('\U00010320', '\U00010323'),
- ('\U00010858', '\U0001085f'), ('\U00010916', '\U0001091b'),
- ('\U00010a40', '\U00010a47'), ('\U00010a7d', '\U00010a7e'),
- ('\U00010b58', '\U00010b5f'), ('\U00010b78', '\U00010b7f'),
- ('\U00010e60', '\U00010e7e'), ('\U00011052', '\U00011065'),
- ('\U0001d360', '\U0001d371'), ('\U0001f100', '\U0001f10a')
- ];
-
- pub fn No(c: char) -> bool {
- bsearch_range_table(c, No_table)
- }
-
- static Pc_table : &'static [(char,char)] = &[
- ('\x5f', '\x5f'), ('\u203f', '\u2040'),
- ('\u2054', '\u2054'), ('\ufe33', '\ufe34'),
- ('\ufe4d', '\ufe4f'), ('\uff3f', '\uff3f')
- ];
-
- pub fn Pc(c: char) -> bool {
- bsearch_range_table(c, Pc_table)
- }
-
- static Pd_table : &'static [(char,char)] = &[
- ('\x2d', '\x2d'), ('\u058a', '\u058a'),
- ('\u05be', '\u05be'), ('\u1400', '\u1400'),
- ('\u1806', '\u1806'), ('\u2010', '\u2015'),
- ('\u2e17', '\u2e17'), ('\u2e1a', '\u2e1a'),
- ('\u2e3a', '\u2e3b'), ('\u301c', '\u301c'),
- ('\u3030', '\u3030'), ('\u30a0', '\u30a0'),
- ('\ufe31', '\ufe32'), ('\ufe58', '\ufe58'),
- ('\ufe63', '\ufe63'), ('\uff0d', '\uff0d')
- ];
-
- pub fn Pd(c: char) -> bool {
- bsearch_range_table(c, Pd_table)
- }
-
- static Pe_table : &'static [(char,char)] = &[
- ('\x29', '\x29'), ('\x5d', '\x5d'),
- ('\x7d', '\x7d'), ('\u0f3b', '\u0f3b'),
- ('\u0f3d', '\u0f3d'), ('\u169c', '\u169c'),
- ('\u2046', '\u2046'), ('\u207e', '\u207e'),
- ('\u208e', '\u208e'), ('\u2309', '\u2309'),
- ('\u230b', '\u230b'), ('\u232a', '\u232a'),
- ('\u2769', '\u2769'), ('\u276b', '\u276b'),
- ('\u276d', '\u276d'), ('\u276f', '\u276f'),
- ('\u2771', '\u2771'), ('\u2773', '\u2773'),
- ('\u2775', '\u2775'), ('\u27c6', '\u27c6'),
- ('\u27e7', '\u27e7'), ('\u27e9', '\u27e9'),
- ('\u27eb', '\u27eb'), ('\u27ed', '\u27ed'),
- ('\u27ef', '\u27ef'), ('\u2984', '\u2984'),
- ('\u2986', '\u2986'), ('\u2988', '\u2988'),
- ('\u298a', '\u298a'), ('\u298c', '\u298c'),
- ('\u298e', '\u298e'), ('\u2990', '\u2990'),
- ('\u2992', '\u2992'), ('\u2994', '\u2994'),
- ('\u2996', '\u2996'), ('\u2998', '\u2998'),
- ('\u29d9', '\u29d9'), ('\u29db', '\u29db'),
- ('\u29fd', '\u29fd'), ('\u2e23', '\u2e23'),
- ('\u2e25', '\u2e25'), ('\u2e27', '\u2e27'),
- ('\u2e29', '\u2e29'), ('\u3009', '\u3009'),
- ('\u300b', '\u300b'), ('\u300d', '\u300d'),
- ('\u300f', '\u300f'), ('\u3011', '\u3011'),
- ('\u3015', '\u3015'), ('\u3017', '\u3017'),
- ('\u3019', '\u3019'), ('\u301b', '\u301b'),
- ('\u301e', '\u301f'), ('\ufd3f', '\ufd3f'),
- ('\ufe18', '\ufe18'), ('\ufe36', '\ufe36'),
- ('\ufe38', '\ufe38'), ('\ufe3a', '\ufe3a'),
- ('\ufe3c', '\ufe3c'), ('\ufe3e', '\ufe3e'),
- ('\ufe40', '\ufe40'), ('\ufe42', '\ufe42'),
- ('\ufe44', '\ufe44'), ('\ufe48', '\ufe48'),
- ('\ufe5a', '\ufe5a'), ('\ufe5c', '\ufe5c'),
- ('\ufe5e', '\ufe5e'), ('\uff09', '\uff09'),
- ('\uff3d', '\uff3d'), ('\uff5d', '\uff5d'),
- ('\uff60', '\uff60'), ('\uff63', '\uff63')
- ];
-
- pub fn Pe(c: char) -> bool {
- bsearch_range_table(c, Pe_table)
- }
-
- static Pf_table : &'static [(char,char)] = &[
- ('\xbb', '\xbb'), ('\u2019', '\u2019'),
- ('\u201d', '\u201d'), ('\u203a', '\u203a'),
- ('\u2e03', '\u2e03'), ('\u2e05', '\u2e05'),
- ('\u2e0a', '\u2e0a'), ('\u2e0d', '\u2e0d'),
- ('\u2e1d', '\u2e1d'), ('\u2e21', '\u2e21')
- ];
-
- pub fn Pf(c: char) -> bool {
- bsearch_range_table(c, Pf_table)
- }
-
- static Pi_table : &'static [(char,char)] = &[
- ('\xab', '\xab'), ('\u2018', '\u2018'),
- ('\u201b', '\u201c'), ('\u201f', '\u201f'),
- ('\u2039', '\u2039'), ('\u2e02', '\u2e02'),
- ('\u2e04', '\u2e04'), ('\u2e09', '\u2e09'),
- ('\u2e0c', '\u2e0c'), ('\u2e1c', '\u2e1c'),
- ('\u2e20', '\u2e20')
- ];
-
- pub fn Pi(c: char) -> bool {
- bsearch_range_table(c, Pi_table)
- }
-
- static Po_table : &'static [(char,char)] = &[
- ('\x21', '\x23'), ('\x25', '\x27'),
- ('\x2a', '\x2a'), ('\x2c', '\x2c'),
- ('\x2e', '\x2f'), ('\x3a', '\x3b'),
- ('\x3f', '\x40'), ('\x5c', '\x5c'),
- ('\xa1', '\xa1'), ('\xa7', '\xa7'),
- ('\xb6', '\xb7'), ('\xbf', '\xbf'),
- ('\u037e', '\u037e'), ('\u0387', '\u0387'),
- ('\u055a', '\u055f'), ('\u0589', '\u0589'),
- ('\u05c0', '\u05c0'), ('\u05c3', '\u05c3'),
- ('\u05c6', '\u05c6'), ('\u05f3', '\u05f4'),
- ('\u0609', '\u060a'), ('\u060c', '\u060d'),
- ('\u061b', '\u061b'), ('\u061e', '\u061f'),
- ('\u066a', '\u066d'), ('\u06d4', '\u06d4'),
- ('\u0700', '\u070d'), ('\u07f7', '\u07f9'),
- ('\u0830', '\u083e'), ('\u085e', '\u085e'),
- ('\u0964', '\u0965'), ('\u0970', '\u0970'),
- ('\u0af0', '\u0af0'), ('\u0df4', '\u0df4'),
- ('\u0e4f', '\u0e4f'), ('\u0e5a', '\u0e5b'),
- ('\u0f04', '\u0f12'), ('\u0f14', '\u0f14'),
- ('\u0f85', '\u0f85'), ('\u0fd0', '\u0fd4'),
- ('\u0fd9', '\u0fda'), ('\u104a', '\u104f'),
- ('\u10fb', '\u10fb'), ('\u1360', '\u1368'),
- ('\u166d', '\u166e'), ('\u16eb', '\u16ed'),
- ('\u1735', '\u1736'), ('\u17d4', '\u17d6'),
- ('\u17d8', '\u17da'), ('\u1800', '\u1805'),
- ('\u1807', '\u180a'), ('\u1944', '\u1945'),
- ('\u1a1e', '\u1a1f'), ('\u1aa0', '\u1aa6'),
- ('\u1aa8', '\u1aad'), ('\u1b5a', '\u1b60'),
- ('\u1bfc', '\u1bff'), ('\u1c3b', '\u1c3f'),
- ('\u1c7e', '\u1cc7'), ('\u1cd3', '\u1cd3'),
- ('\u2016', '\u2017'), ('\u2020', '\u2027'),
- ('\u2030', '\u2038'), ('\u203b', '\u203e'),
- ('\u2041', '\u2043'), ('\u2047', '\u2051'),
- ('\u2053', '\u2053'), ('\u2055', '\u205e'),
- ('\u2cf9', '\u2cfc'), ('\u2cfe', '\u2cff'),
- ('\u2d70', '\u2d70'), ('\u2e00', '\u2e01'),
- ('\u2e06', '\u2e08'), ('\u2e0b', '\u2e0b'),
- ('\u2e0e', '\u2e16'), ('\u2e18', '\u2e19'),
- ('\u2e1b', '\u2e1b'), ('\u2e1e', '\u2e1f'),
- ('\u2e2a', '\u2e2e'), ('\u2e30', '\u2e39'),
- ('\u3001', '\u3003'), ('\u303d', '\u303d'),
- ('\u30fb', '\u30fb'), ('\ua4fe', '\ua4ff'),
- ('\ua60d', '\ua60f'), ('\ua673', '\ua673'),
- ('\ua67e', '\ua67e'), ('\ua6f2', '\ua6f7'),
- ('\ua874', '\ua877'), ('\ua8ce', '\ua8cf'),
- ('\ua8f8', '\ua8fa'), ('\ua92e', '\ua92f'),
- ('\ua95f', '\ua95f'), ('\ua9c1', '\ua9cd'),
- ('\ua9de', '\ua9df'), ('\uaa5c', '\uaa5f'),
- ('\uaade', '\uaadf'), ('\uaaf0', '\uaaf1'),
- ('\uabeb', '\uabeb'), ('\ufe10', '\ufe16'),
- ('\ufe19', '\ufe19'), ('\ufe30', '\ufe30'),
- ('\ufe45', '\ufe46'), ('\ufe49', '\ufe4c'),
- ('\ufe50', '\ufe57'), ('\ufe5f', '\ufe61'),
- ('\ufe68', '\ufe68'), ('\ufe6a', '\ufe6b'),
- ('\uff01', '\uff03'), ('\uff05', '\uff07'),
- ('\uff0a', '\uff0a'), ('\uff0c', '\uff0c'),
- ('\uff0e', '\uff0f'), ('\uff1a', '\uff1b'),
- ('\uff1f', '\uff20'), ('\uff3c', '\uff3c'),
- ('\uff61', '\uff61'), ('\uff64', '\uff65'),
- ('\U00010100', '\U00010102'), ('\U0001039f', '\U0001039f'),
- ('\U000103d0', '\U000103d0'), ('\U00010857', '\U00010857'),
- ('\U0001091f', '\U0001091f'), ('\U0001093f', '\U0001093f'),
- ('\U00010a50', '\U00010a58'), ('\U00010a7f', '\U00010a7f'),
- ('\U00010b39', '\U00010b3f'), ('\U00011047', '\U0001104d'),
- ('\U000110bb', '\U000110bc'), ('\U000110be', '\U000110c1'),
- ('\U00011140', '\U00011143'), ('\U000111c5', '\U000111c8'),
- ('\U00012470', '\U00012473')
- ];
-
- pub fn Po(c: char) -> bool {
- bsearch_range_table(c, Po_table)
- }
-
- static Ps_table : &'static [(char,char)] = &[
- ('\x28', '\x28'), ('\x5b', '\x5b'),
- ('\x7b', '\x7b'), ('\u0f3a', '\u0f3a'),
- ('\u0f3c', '\u0f3c'), ('\u169b', '\u169b'),
- ('\u201a', '\u201a'), ('\u201e', '\u201e'),
- ('\u2045', '\u2045'), ('\u207d', '\u207d'),
- ('\u208d', '\u208d'), ('\u2308', '\u2308'),
- ('\u230a', '\u230a'), ('\u2329', '\u2329'),
- ('\u2768', '\u2768'), ('\u276a', '\u276a'),
- ('\u276c', '\u276c'), ('\u276e', '\u276e'),
- ('\u2770', '\u2770'), ('\u2772', '\u2772'),
- ('\u2774', '\u2774'), ('\u27c5', '\u27c5'),
- ('\u27e6', '\u27e6'), ('\u27e8', '\u27e8'),
- ('\u27ea', '\u27ea'), ('\u27ec', '\u27ec'),
- ('\u27ee', '\u27ee'), ('\u2983', '\u2983'),
- ('\u2985', '\u2985'), ('\u2987', '\u2987'),
- ('\u2989', '\u2989'), ('\u298b', '\u298b'),
- ('\u298d', '\u298d'), ('\u298f', '\u298f'),
- ('\u2991', '\u2991'), ('\u2993', '\u2993'),
- ('\u2995', '\u2995'), ('\u2997', '\u2997'),
- ('\u29d8', '\u29d8'), ('\u29da', '\u29da'),
- ('\u29fc', '\u29fc'), ('\u2e22', '\u2e22'),
- ('\u2e24', '\u2e24'), ('\u2e26', '\u2e26'),
- ('\u2e28', '\u2e28'), ('\u3008', '\u3008'),
- ('\u300a', '\u300a'), ('\u300c', '\u300c'),
- ('\u300e', '\u300e'), ('\u3010', '\u3010'),
- ('\u3014', '\u3014'), ('\u3016', '\u3016'),
- ('\u3018', '\u3018'), ('\u301a', '\u301a'),
- ('\u301d', '\u301d'), ('\ufd3e', '\ufd3e'),
- ('\ufe17', '\ufe17'), ('\ufe35', '\ufe35'),
- ('\ufe37', '\ufe37'), ('\ufe39', '\ufe39'),
- ('\ufe3b', '\ufe3b'), ('\ufe3d', '\ufe3d'),
- ('\ufe3f', '\ufe3f'), ('\ufe41', '\ufe41'),
- ('\ufe43', '\ufe43'), ('\ufe47', '\ufe47'),
- ('\ufe59', '\ufe59'), ('\ufe5b', '\ufe5b'),
- ('\ufe5d', '\ufe5d'), ('\uff08', '\uff08'),
- ('\uff3b', '\uff3b'), ('\uff5b', '\uff5b'),
- ('\uff5f', '\uff5f'), ('\uff62', '\uff62')
- ];
-
- pub fn Ps(c: char) -> bool {
- bsearch_range_table(c, Ps_table)
- }
-
- static Sc_table : &'static [(char,char)] = &[
- ('\x24', '\x24'), ('\xa2', '\xa5'),
- ('\u058f', '\u058f'), ('\u060b', '\u060b'),
- ('\u09f2', '\u09f3'), ('\u09fb', '\u09fb'),
- ('\u0af1', '\u0af1'), ('\u0bf9', '\u0bf9'),
- ('\u0e3f', '\u0e3f'), ('\u17db', '\u17db'),
- ('\u20a0', '\u20ba'), ('\ua838', '\ua838'),
- ('\ufdfc', '\ufdfc'), ('\ufe69', '\ufe69'),
- ('\uff04', '\uff04'), ('\uffe0', '\uffe1'),
- ('\uffe5', '\uffe6')
- ];
-
- pub fn Sc(c: char) -> bool {
- bsearch_range_table(c, Sc_table)
- }
-
- static Sk_table : &'static [(char,char)] = &[
- ('\x5e', '\x5e'), ('\x60', '\x60'),
- ('\xa8', '\xa8'), ('\xaf', '\xaf'),
- ('\xb4', '\xb4'), ('\xb8', '\xb8'),
- ('\u02c2', '\u02c5'), ('\u02d2', '\u02df'),
- ('\u02e5', '\u02eb'), ('\u02ed', '\u02ed'),
- ('\u02ef', '\u02ff'), ('\u0375', '\u0375'),
- ('\u0384', '\u0385'), ('\u1fbd', '\u1fbd'),
- ('\u1fbf', '\u1fc1'), ('\u1fcd', '\u1fcf'),
- ('\u1fdd', '\u1fdf'), ('\u1fed', '\u1fef'),
- ('\u1ffd', '\u1ffe'), ('\u309b', '\u309c'),
- ('\ua700', '\ua716'), ('\ua720', '\ua721'),
- ('\ua789', '\ua78a'), ('\ufbb2', '\ufbc1'),
- ('\uff3e', '\uff3e'), ('\uff40', '\uff40'),
- ('\uffe3', '\uffe3')
- ];
-
- pub fn Sk(c: char) -> bool {
- bsearch_range_table(c, Sk_table)
- }
-
- static Sm_table : &'static [(char,char)] = &[
- ('\x2b', '\x2b'), ('\x3c', '\x3e'),
- ('\x7c', '\x7c'), ('\x7e', '\x7e'),
- ('\xac', '\xac'), ('\xb1', '\xb1'),
- ('\xd7', '\xd7'), ('\xf7', '\xf7'),
- ('\u03f6', '\u03f6'), ('\u0606', '\u0608'),
- ('\u2044', '\u2044'), ('\u2052', '\u2052'),
- ('\u207a', '\u207c'), ('\u208a', '\u208c'),
- ('\u2118', '\u2118'), ('\u2140', '\u2144'),
- ('\u214b', '\u214b'), ('\u2190', '\u2194'),
- ('\u219a', '\u219b'), ('\u21a0', '\u21a0'),
- ('\u21a3', '\u21a3'), ('\u21a6', '\u21a6'),
- ('\u21ae', '\u21ae'), ('\u21ce', '\u21cf'),
- ('\u21d2', '\u21d2'), ('\u21d4', '\u21d4'),
- ('\u21f4', '\u22ff'), ('\u2320', '\u2321'),
- ('\u237c', '\u237c'), ('\u239b', '\u23b3'),
- ('\u23dc', '\u23e1'), ('\u25b7', '\u25b7'),
- ('\u25c1', '\u25c1'), ('\u25f8', '\u25ff'),
- ('\u266f', '\u266f'), ('\u27c0', '\u27c4'),
- ('\u27c7', '\u27e5'), ('\u27f0', '\u27ff'),
- ('\u2900', '\u2982'), ('\u2999', '\u29d7'),
- ('\u29dc', '\u29fb'), ('\u29fe', '\u2aff'),
- ('\u2b30', '\u2b44'), ('\u2b47', '\u2b4c'),
- ('\ufb29', '\ufb29'), ('\ufe62', '\ufe62'),
- ('\ufe64', '\ufe66'), ('\uff0b', '\uff0b'),
- ('\uff1c', '\uff1e'), ('\uff5c', '\uff5c'),
- ('\uff5e', '\uff5e'), ('\uffe2', '\uffe2'),
- ('\uffe9', '\uffec'), ('\U0001d6c1', '\U0001d6c1'),
- ('\U0001d6db', '\U0001d6db'), ('\U0001d6fb', '\U0001d6fb'),
- ('\U0001d715', '\U0001d715'), ('\U0001d735', '\U0001d735'),
- ('\U0001d74f', '\U0001d74f'), ('\U0001d76f', '\U0001d76f'),
- ('\U0001d789', '\U0001d789'), ('\U0001d7a9', '\U0001d7a9'),
- ('\U0001d7c3', '\U0001d7c3'), ('\U0001eef0', '\U0001eef1')
- ];
-
- pub fn Sm(c: char) -> bool {
- bsearch_range_table(c, Sm_table)
- }
-
- static So_table : &'static [(char,char)] = &[
- ('\xa6', '\xa6'), ('\xa9', '\xa9'),
- ('\xae', '\xae'), ('\xb0', '\xb0'),
- ('\u0482', '\u0482'), ('\u060e', '\u060f'),
- ('\u06de', '\u06de'), ('\u06e9', '\u06e9'),
- ('\u06fd', '\u06fe'), ('\u07f6', '\u07f6'),
- ('\u09fa', '\u09fa'), ('\u0b70', '\u0b70'),
- ('\u0bf3', '\u0bf8'), ('\u0bfa', '\u0bfa'),
- ('\u0c7f', '\u0c7f'), ('\u0d79', '\u0d79'),
- ('\u0f01', '\u0f03'), ('\u0f13', '\u0f13'),
- ('\u0f15', '\u0f17'), ('\u0f1a', '\u0f1f'),
- ('\u0f34', '\u0f34'), ('\u0f36', '\u0f36'),
- ('\u0f38', '\u0f38'), ('\u0fbe', '\u0fc5'),
- ('\u0fc7', '\u0fcf'), ('\u0fd5', '\u0fd8'),
- ('\u109e', '\u109f'), ('\u1390', '\u1399'),
- ('\u1940', '\u1940'), ('\u19de', '\u19ff'),
- ('\u1b61', '\u1b6a'), ('\u1b74', '\u1b7c'),
- ('\u2100', '\u2101'), ('\u2103', '\u2106'),
- ('\u2108', '\u2109'), ('\u2114', '\u2114'),
- ('\u2116', '\u2117'), ('\u211e', '\u2123'),
- ('\u2125', '\u2125'), ('\u2127', '\u2127'),
- ('\u2129', '\u2129'), ('\u212e', '\u212e'),
- ('\u213a', '\u213b'), ('\u214a', '\u214a'),
- ('\u214c', '\u214d'), ('\u214f', '\u214f'),
- ('\u2195', '\u2199'), ('\u219c', '\u219f'),
- ('\u21a1', '\u21a2'), ('\u21a4', '\u21a5'),
- ('\u21a7', '\u21ad'), ('\u21af', '\u21cd'),
- ('\u21d0', '\u21d1'), ('\u21d3', '\u21d3'),
- ('\u21d5', '\u21f3'), ('\u2300', '\u2307'),
- ('\u230c', '\u231f'), ('\u2322', '\u2328'),
- ('\u232b', '\u237b'), ('\u237d', '\u239a'),
- ('\u23b4', '\u23db'), ('\u23e2', '\u244a'),
- ('\u249c', '\u24e9'), ('\u2500', '\u25b6'),
- ('\u25b8', '\u25c0'), ('\u25c2', '\u25f7'),
- ('\u2600', '\u266e'), ('\u2670', '\u2767'),
- ('\u2794', '\u27bf'), ('\u2800', '\u28ff'),
- ('\u2b00', '\u2b2f'), ('\u2b45', '\u2b46'),
- ('\u2b50', '\u2b59'), ('\u2ce5', '\u2cea'),
- ('\u2e80', '\u2ffb'), ('\u3004', '\u3004'),
- ('\u3012', '\u3013'), ('\u3020', '\u3020'),
- ('\u3036', '\u3037'), ('\u303e', '\u303f'),
- ('\u3190', '\u3191'), ('\u3196', '\u319f'),
- ('\u31c0', '\u31e3'), ('\u3200', '\u321e'),
- ('\u322a', '\u3247'), ('\u3250', '\u3250'),
- ('\u3260', '\u327f'), ('\u328a', '\u32b0'),
- ('\u32c0', '\u33ff'), ('\u4dc0', '\u4dff'),
- ('\ua490', '\ua4c6'), ('\ua828', '\ua82b'),
- ('\ua836', '\ua837'), ('\ua839', '\ua839'),
- ('\uaa77', '\uaa79'), ('\ufdfd', '\ufdfd'),
- ('\uffe4', '\uffe4'), ('\uffe8', '\uffe8'),
- ('\uffed', '\uffee'), ('\ufffc', '\ufffd'),
- ('\U00010137', '\U0001013f'), ('\U00010179', '\U00010189'),
- ('\U00010190', '\U000101fc'), ('\U0001d000', '\U0001d164'),
- ('\U0001d16a', '\U0001d16c'), ('\U0001d183', '\U0001d184'),
- ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d241'),
- ('\U0001d245', '\U0001d356'), ('\U0001f000', '\U0001f0df'),
- ('\U0001f110', '\U0001f773')
- ];
-
- pub fn So(c: char) -> bool {
- bsearch_range_table(c, So_table)
- }
-
- static Zl_table : &'static [(char,char)] = &[
- ('\u2028', '\u2028')
- ];
-
- pub fn Zl(c: char) -> bool {
- bsearch_range_table(c, Zl_table)
- }
-
- static Zp_table : &'static [(char,char)] = &[
- ('\u2029', '\u2029')
- ];
-
- pub fn Zp(c: char) -> bool {
- bsearch_range_table(c, Zp_table)
- }
-
- static Zs_table : &'static [(char,char)] = &[
- ('\x20', '\x20'), ('\xa0', '\xa0'),
- ('\u1680', '\u1680'), ('\u2000', '\u200a'),
- ('\u202f', '\u202f'), ('\u205f', '\u205f'),
- ('\u3000', '\u3000')
- ];
-
- pub fn Zs(c: char) -> bool {
- bsearch_range_table(c, Zs_table)
- }
-
-}
-pub mod decompose {
- use option::Option;
- use option::{Some, None};
- use vec::ImmutableVector;
-
- fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
- use cmp::{Equal, Less, Greater};
- match r.bsearch(|&(val, _)| {
- if c == val { Equal }
- else if val < c { Less }
- else { Greater }
- }) {
- Some(idx) => {
- let (_, result) = r[idx];
- Some(result)
- }
- None => None
- }
- }
-
-
- fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
- use cmp::{Equal, Less, Greater};
- match r.bsearch(|&(lo, hi, _)| {
- if lo <= c && c <= hi { Equal }
- else if hi < c { Less }
- else { Greater }
- }) {
- Some(idx) => {
- let (_, _, result) = r[idx];
- result
- }
- None => 0
- }
- }
-
-
- // Canonical decompositions
- static canonical_table : &'static [(char, &'static [char])] = &[
- ('\xc0', &['\x41', '\u0300']), ('\xc1', &['\x41', '\u0301']), ('\xc2', &['\x41', '\u0302']),
- ('\xc3', &['\x41', '\u0303']), ('\xc4', &['\x41', '\u0308']), ('\xc5', &['\x41', '\u030a']),
- ('\xc7', &['\x43', '\u0327']), ('\xc8', &['\x45', '\u0300']), ('\xc9', &['\x45', '\u0301']),
- ('\xca', &['\x45', '\u0302']), ('\xcb', &['\x45', '\u0308']), ('\xcc', &['\x49', '\u0300']),
- ('\xcd', &['\x49', '\u0301']), ('\xce', &['\x49', '\u0302']), ('\xcf', &['\x49', '\u0308']),
- ('\xd1', &['\x4e', '\u0303']), ('\xd2', &['\x4f', '\u0300']), ('\xd3', &['\x4f', '\u0301']),
- ('\xd4', &['\x4f', '\u0302']), ('\xd5', &['\x4f', '\u0303']), ('\xd6', &['\x4f', '\u0308']),
- ('\xd9', &['\x55', '\u0300']), ('\xda', &['\x55', '\u0301']), ('\xdb', &['\x55', '\u0302']),
- ('\xdc', &['\x55', '\u0308']), ('\xdd', &['\x59', '\u0301']), ('\xe0', &['\x61', '\u0300']),
- ('\xe1', &['\x61', '\u0301']), ('\xe2', &['\x61', '\u0302']), ('\xe3', &['\x61', '\u0303']),
- ('\xe4', &['\x61', '\u0308']), ('\xe5', &['\x61', '\u030a']), ('\xe7', &['\x63', '\u0327']),
- ('\xe8', &['\x65', '\u0300']), ('\xe9', &['\x65', '\u0301']), ('\xea', &['\x65', '\u0302']),
- ('\xeb', &['\x65', '\u0308']), ('\xec', &['\x69', '\u0300']), ('\xed', &['\x69', '\u0301']),
- ('\xee', &['\x69', '\u0302']), ('\xef', &['\x69', '\u0308']), ('\xf1', &['\x6e', '\u0303']),
- ('\xf2', &['\x6f', '\u0300']), ('\xf3', &['\x6f', '\u0301']), ('\xf4', &['\x6f', '\u0302']),
- ('\xf5', &['\x6f', '\u0303']), ('\xf6', &['\x6f', '\u0308']), ('\xf9', &['\x75', '\u0300']),
- ('\xfa', &['\x75', '\u0301']), ('\xfb', &['\x75', '\u0302']), ('\xfc', &['\x75', '\u0308']),
- ('\xfd', &['\x79', '\u0301']), ('\xff', &['\x79', '\u0308']), ('\u0100', &['\x41',
- '\u0304']), ('\u0101', &['\x61', '\u0304']), ('\u0102', &['\x41', '\u0306']), ('\u0103',
- &['\x61', '\u0306']), ('\u0104', &['\x41', '\u0328']), ('\u0105', &['\x61', '\u0328']),
- ('\u0106', &['\x43', '\u0301']), ('\u0107', &['\x63', '\u0301']), ('\u0108', &['\x43',
- '\u0302']), ('\u0109', &['\x63', '\u0302']), ('\u010a', &['\x43', '\u0307']), ('\u010b',
- &['\x63', '\u0307']), ('\u010c', &['\x43', '\u030c']), ('\u010d', &['\x63', '\u030c']),
- ('\u010e', &['\x44', '\u030c']), ('\u010f', &['\x64', '\u030c']), ('\u0112', &['\x45',
- '\u0304']), ('\u0113', &['\x65', '\u0304']), ('\u0114', &['\x45', '\u0306']), ('\u0115',
- &['\x65', '\u0306']), ('\u0116', &['\x45', '\u0307']), ('\u0117', &['\x65', '\u0307']),
- ('\u0118', &['\x45', '\u0328']), ('\u0119', &['\x65', '\u0328']), ('\u011a', &['\x45',
- '\u030c']), ('\u011b', &['\x65', '\u030c']), ('\u011c', &['\x47', '\u0302']), ('\u011d',
- &['\x67', '\u0302']), ('\u011e', &['\x47', '\u0306']), ('\u011f', &['\x67', '\u0306']),
- ('\u0120', &['\x47', '\u0307']), ('\u0121', &['\x67', '\u0307']), ('\u0122', &['\x47',
- '\u0327']), ('\u0123', &['\x67', '\u0327']), ('\u0124', &['\x48', '\u0302']), ('\u0125',
- &['\x68', '\u0302']), ('\u0128', &['\x49', '\u0303']), ('\u0129', &['\x69', '\u0303']),
- ('\u012a', &['\x49', '\u0304']), ('\u012b', &['\x69', '\u0304']), ('\u012c', &['\x49',
- '\u0306']), ('\u012d', &['\x69', '\u0306']), ('\u012e', &['\x49', '\u0328']), ('\u012f',
- &['\x69', '\u0328']), ('\u0130', &['\x49', '\u0307']), ('\u0134', &['\x4a', '\u0302']),
- ('\u0135', &['\x6a', '\u0302']), ('\u0136', &['\x4b', '\u0327']), ('\u0137', &['\x6b',
- '\u0327']), ('\u0139', &['\x4c', '\u0301']), ('\u013a', &['\x6c', '\u0301']), ('\u013b',
- &['\x4c', '\u0327']), ('\u013c', &['\x6c', '\u0327']), ('\u013d', &['\x4c', '\u030c']),
- ('\u013e', &['\x6c', '\u030c']), ('\u0143', &['\x4e', '\u0301']), ('\u0144', &['\x6e',
- '\u0301']), ('\u0145', &['\x4e', '\u0327']), ('\u0146', &['\x6e', '\u0327']), ('\u0147',
- &['\x4e', '\u030c']), ('\u0148', &['\x6e', '\u030c']), ('\u014c', &['\x4f', '\u0304']),
- ('\u014d', &['\x6f', '\u0304']), ('\u014e', &['\x4f', '\u0306']), ('\u014f', &['\x6f',
- '\u0306']), ('\u0150', &['\x4f', '\u030b']), ('\u0151', &['\x6f', '\u030b']), ('\u0154',
- &['\x52', '\u0301']), ('\u0155', &['\x72', '\u0301']), ('\u0156', &['\x52', '\u0327']),
- ('\u0157', &['\x72', '\u0327']), ('\u0158', &['\x52', '\u030c']), ('\u0159', &['\x72',
- '\u030c']), ('\u015a', &['\x53', '\u0301']), ('\u015b', &['\x73', '\u0301']), ('\u015c',
- &['\x53', '\u0302']), ('\u015d', &['\x73', '\u0302']), ('\u015e', &['\x53', '\u0327']),
- ('\u015f', &['\x73', '\u0327']), ('\u0160', &['\x53', '\u030c']), ('\u0161', &['\x73',
- '\u030c']), ('\u0162', &['\x54', '\u0327']), ('\u0163', &['\x74', '\u0327']), ('\u0164',
- &['\x54', '\u030c']), ('\u0165', &['\x74', '\u030c']), ('\u0168', &['\x55', '\u0303']),
- ('\u0169', &['\x75', '\u0303']), ('\u016a', &['\x55', '\u0304']), ('\u016b', &['\x75',
- '\u0304']), ('\u016c', &['\x55', '\u0306']), ('\u016d', &['\x75', '\u0306']), ('\u016e',
- &['\x55', '\u030a']), ('\u016f', &['\x75', '\u030a']), ('\u0170', &['\x55', '\u030b']),
- ('\u0171', &['\x75', '\u030b']), ('\u0172', &['\x55', '\u0328']), ('\u0173', &['\x75',
- '\u0328']), ('\u0174', &['\x57', '\u0302']), ('\u0175', &['\x77', '\u0302']), ('\u0176',
- &['\x59', '\u0302']), ('\u0177', &['\x79', '\u0302']), ('\u0178', &['\x59', '\u0308']),
- ('\u0179', &['\x5a', '\u0301']), ('\u017a', &['\x7a', '\u0301']), ('\u017b', &['\x5a',
- '\u0307']), ('\u017c', &['\x7a', '\u0307']), ('\u017d', &['\x5a', '\u030c']), ('\u017e',
- &['\x7a', '\u030c']), ('\u01a0', &['\x4f', '\u031b']), ('\u01a1', &['\x6f', '\u031b']),
- ('\u01af', &['\x55', '\u031b']), ('\u01b0', &['\x75', '\u031b']), ('\u01cd', &['\x41',
- '\u030c']), ('\u01ce', &['\x61', '\u030c']), ('\u01cf', &['\x49', '\u030c']), ('\u01d0',
- &['\x69', '\u030c']), ('\u01d1', &['\x4f', '\u030c']), ('\u01d2', &['\x6f', '\u030c']),
- ('\u01d3', &['\x55', '\u030c']), ('\u01d4', &['\x75', '\u030c']), ('\u01d5', &['\xdc',
- '\u0304']), ('\u01d6', &['\xfc', '\u0304']), ('\u01d7', &['\xdc', '\u0301']), ('\u01d8',
- &['\xfc', '\u0301']), ('\u01d9', &['\xdc', '\u030c']), ('\u01da', &['\xfc', '\u030c']),
- ('\u01db', &['\xdc', '\u0300']), ('\u01dc', &['\xfc', '\u0300']), ('\u01de', &['\xc4',
- '\u0304']), ('\u01df', &['\xe4', '\u0304']), ('\u01e0', &['\u0226', '\u0304']), ('\u01e1',
- &['\u0227', '\u0304']), ('\u01e2', &['\xc6', '\u0304']), ('\u01e3', &['\xe6', '\u0304']),
- ('\u01e6', &['\x47', '\u030c']), ('\u01e7', &['\x67', '\u030c']), ('\u01e8', &['\x4b',
- '\u030c']), ('\u01e9', &['\x6b', '\u030c']), ('\u01ea', &['\x4f', '\u0328']), ('\u01eb',
- &['\x6f', '\u0328']), ('\u01ec', &['\u01ea', '\u0304']), ('\u01ed', &['\u01eb', '\u0304']),
- ('\u01ee', &['\u01b7', '\u030c']), ('\u01ef', &['\u0292', '\u030c']), ('\u01f0', &['\x6a',
- '\u030c']), ('\u01f4', &['\x47', '\u0301']), ('\u01f5', &['\x67', '\u0301']), ('\u01f8',
- &['\x4e', '\u0300']), ('\u01f9', &['\x6e', '\u0300']), ('\u01fa', &['\xc5', '\u0301']),
- ('\u01fb', &['\xe5', '\u0301']), ('\u01fc', &['\xc6', '\u0301']), ('\u01fd', &['\xe6',
- '\u0301']), ('\u01fe', &['\xd8', '\u0301']), ('\u01ff', &['\xf8', '\u0301']), ('\u0200',
- &['\x41', '\u030f']), ('\u0201', &['\x61', '\u030f']), ('\u0202', &['\x41', '\u0311']),
- ('\u0203', &['\x61', '\u0311']), ('\u0204', &['\x45', '\u030f']), ('\u0205', &['\x65',
- '\u030f']), ('\u0206', &['\x45', '\u0311']), ('\u0207', &['\x65', '\u0311']), ('\u0208',
- &['\x49', '\u030f']), ('\u0209', &['\x69', '\u030f']), ('\u020a', &['\x49', '\u0311']),
- ('\u020b', &['\x69', '\u0311']), ('\u020c', &['\x4f', '\u030f']), ('\u020d', &['\x6f',
- '\u030f']), ('\u020e', &['\x4f', '\u0311']), ('\u020f', &['\x6f', '\u0311']), ('\u0210',
- &['\x52', '\u030f']), ('\u0211', &['\x72', '\u030f']), ('\u0212', &['\x52', '\u0311']),
- ('\u0213', &['\x72', '\u0311']), ('\u0214', &['\x55', '\u030f']), ('\u0215', &['\x75',
- '\u030f']), ('\u0216', &['\x55', '\u0311']), ('\u0217', &['\x75', '\u0311']), ('\u0218',
- &['\x53', '\u0326']), ('\u0219', &['\x73', '\u0326']), ('\u021a', &['\x54', '\u0326']),
- ('\u021b', &['\x74', '\u0326']), ('\u021e', &['\x48', '\u030c']), ('\u021f', &['\x68',
- '\u030c']), ('\u0226', &['\x41', '\u0307']), ('\u0227', &['\x61', '\u0307']), ('\u0228',
- &['\x45', '\u0327']), ('\u0229', &['\x65', '\u0327']), ('\u022a', &['\xd6', '\u0304']),
- ('\u022b', &['\xf6', '\u0304']), ('\u022c', &['\xd5', '\u0304']), ('\u022d', &['\xf5',
- '\u0304']), ('\u022e', &['\x4f', '\u0307']), ('\u022f', &['\x6f', '\u0307']), ('\u0230',
- &['\u022e', '\u0304']), ('\u0231', &['\u022f', '\u0304']), ('\u0232', &['\x59', '\u0304']),
- ('\u0233', &['\x79', '\u0304']), ('\u0340', &['\u0300']), ('\u0341', &['\u0301']),
- ('\u0343', &['\u0313']), ('\u0344', &['\u0308', '\u0301']), ('\u0374', &['\u02b9']),
- ('\u037e', &['\x3b']), ('\u0385', &['\xa8', '\u0301']), ('\u0386', &['\u0391', '\u0301']),
- ('\u0387', &['\xb7']), ('\u0388', &['\u0395', '\u0301']), ('\u0389', &['\u0397', '\u0301']),
- ('\u038a', &['\u0399', '\u0301']), ('\u038c', &['\u039f', '\u0301']), ('\u038e', &['\u03a5',
- '\u0301']), ('\u038f', &['\u03a9', '\u0301']), ('\u0390', &['\u03ca', '\u0301']), ('\u03aa',
- &['\u0399', '\u0308']), ('\u03ab', &['\u03a5', '\u0308']), ('\u03ac', &['\u03b1',
- '\u0301']), ('\u03ad', &['\u03b5', '\u0301']), ('\u03ae', &['\u03b7', '\u0301']), ('\u03af',
- &['\u03b9', '\u0301']), ('\u03b0', &['\u03cb', '\u0301']), ('\u03ca', &['\u03b9',
- '\u0308']), ('\u03cb', &['\u03c5', '\u0308']), ('\u03cc', &['\u03bf', '\u0301']), ('\u03cd',
- &['\u03c5', '\u0301']), ('\u03ce', &['\u03c9', '\u0301']), ('\u03d3', &['\u03d2',
- '\u0301']), ('\u03d4', &['\u03d2', '\u0308']), ('\u0400', &['\u0415', '\u0300']), ('\u0401',
- &['\u0415', '\u0308']), ('\u0403', &['\u0413', '\u0301']), ('\u0407', &['\u0406',
- '\u0308']), ('\u040c', &['\u041a', '\u0301']), ('\u040d', &['\u0418', '\u0300']), ('\u040e',
- &['\u0423', '\u0306']), ('\u0419', &['\u0418', '\u0306']), ('\u0439', &['\u0438',
- '\u0306']), ('\u0450', &['\u0435', '\u0300']), ('\u0451', &['\u0435', '\u0308']), ('\u0453',
- &['\u0433', '\u0301']), ('\u0457', &['\u0456', '\u0308']), ('\u045c', &['\u043a',
- '\u0301']), ('\u045d', &['\u0438', '\u0300']), ('\u045e', &['\u0443', '\u0306']), ('\u0476',
- &['\u0474', '\u030f']), ('\u0477', &['\u0475', '\u030f']), ('\u04c1', &['\u0416',
- '\u0306']), ('\u04c2', &['\u0436', '\u0306']), ('\u04d0', &['\u0410', '\u0306']), ('\u04d1',
- &['\u0430', '\u0306']), ('\u04d2', &['\u0410', '\u0308']), ('\u04d3', &['\u0430',
- '\u0308']), ('\u04d6', &['\u0415', '\u0306']), ('\u04d7', &['\u0435', '\u0306']), ('\u04da',
- &['\u04d8', '\u0308']), ('\u04db', &['\u04d9', '\u0308']), ('\u04dc', &['\u0416',
- '\u0308']), ('\u04dd', &['\u0436', '\u0308']), ('\u04de', &['\u0417', '\u0308']), ('\u04df',
- &['\u0437', '\u0308']), ('\u04e2', &['\u0418', '\u0304']), ('\u04e3', &['\u0438',
- '\u0304']), ('\u04e4', &['\u0418', '\u0308']), ('\u04e5', &['\u0438', '\u0308']), ('\u04e6',
- &['\u041e', '\u0308']), ('\u04e7', &['\u043e', '\u0308']), ('\u04ea', &['\u04e8',
- '\u0308']), ('\u04eb', &['\u04e9', '\u0308']), ('\u04ec', &['\u042d', '\u0308']), ('\u04ed',
- &['\u044d', '\u0308']), ('\u04ee', &['\u0423', '\u0304']), ('\u04ef', &['\u0443',
- '\u0304']), ('\u04f0', &['\u0423', '\u0308']), ('\u04f1', &['\u0443', '\u0308']), ('\u04f2',
- &['\u0423', '\u030b']), ('\u04f3', &['\u0443', '\u030b']), ('\u04f4', &['\u0427',
- '\u0308']), ('\u04f5', &['\u0447', '\u0308']), ('\u04f8', &['\u042b', '\u0308']), ('\u04f9',
- &['\u044b', '\u0308']), ('\u0622', &['\u0627', '\u0653']), ('\u0623', &['\u0627',
- '\u0654']), ('\u0624', &['\u0648', '\u0654']), ('\u0625', &['\u0627', '\u0655']), ('\u0626',
- &['\u064a', '\u0654']), ('\u06c0', &['\u06d5', '\u0654']), ('\u06c2', &['\u06c1',
- '\u0654']), ('\u06d3', &['\u06d2', '\u0654']), ('\u0929', &['\u0928', '\u093c']), ('\u0931',
- &['\u0930', '\u093c']), ('\u0934', &['\u0933', '\u093c']), ('\u0958', &['\u0915',
- '\u093c']), ('\u0959', &['\u0916', '\u093c']), ('\u095a', &['\u0917', '\u093c']), ('\u095b',
- &['\u091c', '\u093c']), ('\u095c', &['\u0921', '\u093c']), ('\u095d', &['\u0922',
- '\u093c']), ('\u095e', &['\u092b', '\u093c']), ('\u095f', &['\u092f', '\u093c']), ('\u09cb',
- &['\u09c7', '\u09be']), ('\u09cc', &['\u09c7', '\u09d7']), ('\u09dc', &['\u09a1',
- '\u09bc']), ('\u09dd', &['\u09a2', '\u09bc']), ('\u09df', &['\u09af', '\u09bc']), ('\u0a33',
- &['\u0a32', '\u0a3c']), ('\u0a36', &['\u0a38', '\u0a3c']), ('\u0a59', &['\u0a16',
- '\u0a3c']), ('\u0a5a', &['\u0a17', '\u0a3c']), ('\u0a5b', &['\u0a1c', '\u0a3c']), ('\u0a5e',
- &['\u0a2b', '\u0a3c']), ('\u0b48', &['\u0b47', '\u0b56']), ('\u0b4b', &['\u0b47',
- '\u0b3e']), ('\u0b4c', &['\u0b47', '\u0b57']), ('\u0b5c', &['\u0b21', '\u0b3c']), ('\u0b5d',
- &['\u0b22', '\u0b3c']), ('\u0b94', &['\u0b92', '\u0bd7']), ('\u0bca', &['\u0bc6',
- '\u0bbe']), ('\u0bcb', &['\u0bc7', '\u0bbe']), ('\u0bcc', &['\u0bc6', '\u0bd7']), ('\u0c48',
- &['\u0c46', '\u0c56']), ('\u0cc0', &['\u0cbf', '\u0cd5']), ('\u0cc7', &['\u0cc6',
- '\u0cd5']), ('\u0cc8', &['\u0cc6', '\u0cd6']), ('\u0cca', &['\u0cc6', '\u0cc2']), ('\u0ccb',
- &['\u0cca', '\u0cd5']), ('\u0d4a', &['\u0d46', '\u0d3e']), ('\u0d4b', &['\u0d47',
- '\u0d3e']), ('\u0d4c', &['\u0d46', '\u0d57']), ('\u0dda', &['\u0dd9', '\u0dca']), ('\u0ddc',
- &['\u0dd9', '\u0dcf']), ('\u0ddd', &['\u0ddc', '\u0dca']), ('\u0dde', &['\u0dd9',
- '\u0ddf']), ('\u0f43', &['\u0f42', '\u0fb7']), ('\u0f4d', &['\u0f4c', '\u0fb7']), ('\u0f52',
- &['\u0f51', '\u0fb7']), ('\u0f57', &['\u0f56', '\u0fb7']), ('\u0f5c', &['\u0f5b',
- '\u0fb7']), ('\u0f69', &['\u0f40', '\u0fb5']), ('\u0f73', &['\u0f71', '\u0f72']), ('\u0f75',
- &['\u0f71', '\u0f74']), ('\u0f76', &['\u0fb2', '\u0f80']), ('\u0f78', &['\u0fb3',
- '\u0f80']), ('\u0f81', &['\u0f71', '\u0f80']), ('\u0f93', &['\u0f92', '\u0fb7']), ('\u0f9d',
- &['\u0f9c', '\u0fb7']), ('\u0fa2', &['\u0fa1', '\u0fb7']), ('\u0fa7', &['\u0fa6',
- '\u0fb7']), ('\u0fac', &['\u0fab', '\u0fb7']), ('\u0fb9', &['\u0f90', '\u0fb5']), ('\u1026',
- &['\u1025', '\u102e']), ('\u1b06', &['\u1b05', '\u1b35']), ('\u1b08', &['\u1b07',
- '\u1b35']), ('\u1b0a', &['\u1b09', '\u1b35']), ('\u1b0c', &['\u1b0b', '\u1b35']), ('\u1b0e',
- &['\u1b0d', '\u1b35']), ('\u1b12', &['\u1b11', '\u1b35']), ('\u1b3b', &['\u1b3a',
- '\u1b35']), ('\u1b3d', &['\u1b3c', '\u1b35']), ('\u1b40', &['\u1b3e', '\u1b35']), ('\u1b41',
- &['\u1b3f', '\u1b35']), ('\u1b43', &['\u1b42', '\u1b35']), ('\u1e00', &['\x41', '\u0325']),
- ('\u1e01', &['\x61', '\u0325']), ('\u1e02', &['\x42', '\u0307']), ('\u1e03', &['\x62',
- '\u0307']), ('\u1e04', &['\x42', '\u0323']), ('\u1e05', &['\x62', '\u0323']), ('\u1e06',
- &['\x42', '\u0331']), ('\u1e07', &['\x62', '\u0331']), ('\u1e08', &['\xc7', '\u0301']),
- ('\u1e09', &['\xe7', '\u0301']), ('\u1e0a', &['\x44', '\u0307']), ('\u1e0b', &['\x64',
- '\u0307']), ('\u1e0c', &['\x44', '\u0323']), ('\u1e0d', &['\x64', '\u0323']), ('\u1e0e',
- &['\x44', '\u0331']), ('\u1e0f', &['\x64', '\u0331']), ('\u1e10', &['\x44', '\u0327']),
- ('\u1e11', &['\x64', '\u0327']), ('\u1e12', &['\x44', '\u032d']), ('\u1e13', &['\x64',
- '\u032d']), ('\u1e14', &['\u0112', '\u0300']), ('\u1e15', &['\u0113', '\u0300']), ('\u1e16',
- &['\u0112', '\u0301']), ('\u1e17', &['\u0113', '\u0301']), ('\u1e18', &['\x45', '\u032d']),
- ('\u1e19', &['\x65', '\u032d']), ('\u1e1a', &['\x45', '\u0330']), ('\u1e1b', &['\x65',
- '\u0330']), ('\u1e1c', &['\u0228', '\u0306']), ('\u1e1d', &['\u0229', '\u0306']), ('\u1e1e',
- &['\x46', '\u0307']), ('\u1e1f', &['\x66', '\u0307']), ('\u1e20', &['\x47', '\u0304']),
- ('\u1e21', &['\x67', '\u0304']), ('\u1e22', &['\x48', '\u0307']), ('\u1e23', &['\x68',
- '\u0307']), ('\u1e24', &['\x48', '\u0323']), ('\u1e25', &['\x68', '\u0323']), ('\u1e26',
- &['\x48', '\u0308']), ('\u1e27', &['\x68', '\u0308']), ('\u1e28', &['\x48', '\u0327']),
- ('\u1e29', &['\x68', '\u0327']), ('\u1e2a', &['\x48', '\u032e']), ('\u1e2b', &['\x68',
- '\u032e']), ('\u1e2c', &['\x49', '\u0330']), ('\u1e2d', &['\x69', '\u0330']), ('\u1e2e',
- &['\xcf', '\u0301']), ('\u1e2f', &['\xef', '\u0301']), ('\u1e30', &['\x4b', '\u0301']),
- ('\u1e31', &['\x6b', '\u0301']), ('\u1e32', &['\x4b', '\u0323']), ('\u1e33', &['\x6b',
- '\u0323']), ('\u1e34', &['\x4b', '\u0331']), ('\u1e35', &['\x6b', '\u0331']), ('\u1e36',
- &['\x4c', '\u0323']), ('\u1e37', &['\x6c', '\u0323']), ('\u1e38', &['\u1e36', '\u0304']),
- ('\u1e39', &['\u1e37', '\u0304']), ('\u1e3a', &['\x4c', '\u0331']), ('\u1e3b', &['\x6c',
- '\u0331']), ('\u1e3c', &['\x4c', '\u032d']), ('\u1e3d', &['\x6c', '\u032d']), ('\u1e3e',
- &['\x4d', '\u0301']), ('\u1e3f', &['\x6d', '\u0301']), ('\u1e40', &['\x4d', '\u0307']),
- ('\u1e41', &['\x6d', '\u0307']), ('\u1e42', &['\x4d', '\u0323']), ('\u1e43', &['\x6d',
- '\u0323']), ('\u1e44', &['\x4e', '\u0307']), ('\u1e45', &['\x6e', '\u0307']), ('\u1e46',
- &['\x4e', '\u0323']), ('\u1e47', &['\x6e', '\u0323']), ('\u1e48', &['\x4e', '\u0331']),
- ('\u1e49', &['\x6e', '\u0331']), ('\u1e4a', &['\x4e', '\u032d']), ('\u1e4b', &['\x6e',
- '\u032d']), ('\u1e4c', &['\xd5', '\u0301']), ('\u1e4d', &['\xf5', '\u0301']), ('\u1e4e',
- &['\xd5', '\u0308']), ('\u1e4f', &['\xf5', '\u0308']), ('\u1e50', &['\u014c', '\u0300']),
- ('\u1e51', &['\u014d', '\u0300']), ('\u1e52', &['\u014c', '\u0301']), ('\u1e53', &['\u014d',
- '\u0301']), ('\u1e54', &['\x50', '\u0301']), ('\u1e55', &['\x70', '\u0301']), ('\u1e56',
- &['\x50', '\u0307']), ('\u1e57', &['\x70', '\u0307']), ('\u1e58', &['\x52', '\u0307']),
- ('\u1e59', &['\x72', '\u0307']), ('\u1e5a', &['\x52', '\u0323']), ('\u1e5b', &['\x72',
- '\u0323']), ('\u1e5c', &['\u1e5a', '\u0304']), ('\u1e5d', &['\u1e5b', '\u0304']), ('\u1e5e',
- &['\x52', '\u0331']), ('\u1e5f', &['\x72', '\u0331']), ('\u1e60', &['\x53', '\u0307']),
- ('\u1e61', &['\x73', '\u0307']), ('\u1e62', &['\x53', '\u0323']), ('\u1e63', &['\x73',
- '\u0323']), ('\u1e64', &['\u015a', '\u0307']), ('\u1e65', &['\u015b', '\u0307']), ('\u1e66',
- &['\u0160', '\u0307']), ('\u1e67', &['\u0161', '\u0307']), ('\u1e68', &['\u1e62',
- '\u0307']), ('\u1e69', &['\u1e63', '\u0307']), ('\u1e6a', &['\x54', '\u0307']), ('\u1e6b',
- &['\x74', '\u0307']), ('\u1e6c', &['\x54', '\u0323']), ('\u1e6d', &['\x74', '\u0323']),
- ('\u1e6e', &['\x54', '\u0331']), ('\u1e6f', &['\x74', '\u0331']), ('\u1e70', &['\x54',
- '\u032d']), ('\u1e71', &['\x74', '\u032d']), ('\u1e72', &['\x55', '\u0324']), ('\u1e73',
- &['\x75', '\u0324']), ('\u1e74', &['\x55', '\u0330']), ('\u1e75', &['\x75', '\u0330']),
- ('\u1e76', &['\x55', '\u032d']), ('\u1e77', &['\x75', '\u032d']), ('\u1e78', &['\u0168',
- '\u0301']), ('\u1e79', &['\u0169', '\u0301']), ('\u1e7a', &['\u016a', '\u0308']), ('\u1e7b',
- &['\u016b', '\u0308']), ('\u1e7c', &['\x56', '\u0303']), ('\u1e7d', &['\x76', '\u0303']),
- ('\u1e7e', &['\x56', '\u0323']), ('\u1e7f', &['\x76', '\u0323']), ('\u1e80', &['\x57',
- '\u0300']), ('\u1e81', &['\x77', '\u0300']), ('\u1e82', &['\x57', '\u0301']), ('\u1e83',
- &['\x77', '\u0301']), ('\u1e84', &['\x57', '\u0308']), ('\u1e85', &['\x77', '\u0308']),
- ('\u1e86', &['\x57', '\u0307']), ('\u1e87', &['\x77', '\u0307']), ('\u1e88', &['\x57',
- '\u0323']), ('\u1e89', &['\x77', '\u0323']), ('\u1e8a', &['\x58', '\u0307']), ('\u1e8b',
- &['\x78', '\u0307']), ('\u1e8c', &['\x58', '\u0308']), ('\u1e8d', &['\x78', '\u0308']),
- ('\u1e8e', &['\x59', '\u0307']), ('\u1e8f', &['\x79', '\u0307']), ('\u1e90', &['\x5a',
- '\u0302']), ('\u1e91', &['\x7a', '\u0302']), ('\u1e92', &['\x5a', '\u0323']), ('\u1e93',
- &['\x7a', '\u0323']), ('\u1e94', &['\x5a', '\u0331']), ('\u1e95', &['\x7a', '\u0331']),
- ('\u1e96', &['\x68', '\u0331']), ('\u1e97', &['\x74', '\u0308']), ('\u1e98', &['\x77',
- '\u030a']), ('\u1e99', &['\x79', '\u030a']), ('\u1e9b', &['\u017f', '\u0307']), ('\u1ea0',
- &['\x41', '\u0323']), ('\u1ea1', &['\x61', '\u0323']), ('\u1ea2', &['\x41', '\u0309']),
- ('\u1ea3', &['\x61', '\u0309']), ('\u1ea4', &['\xc2', '\u0301']), ('\u1ea5', &['\xe2',
- '\u0301']), ('\u1ea6', &['\xc2', '\u0300']), ('\u1ea7', &['\xe2', '\u0300']), ('\u1ea8',
- &['\xc2', '\u0309']), ('\u1ea9', &['\xe2', '\u0309']), ('\u1eaa', &['\xc2', '\u0303']),
- ('\u1eab', &['\xe2', '\u0303']), ('\u1eac', &['\u1ea0', '\u0302']), ('\u1ead', &['\u1ea1',
- '\u0302']), ('\u1eae', &['\u0102', '\u0301']), ('\u1eaf', &['\u0103', '\u0301']), ('\u1eb0',
- &['\u0102', '\u0300']), ('\u1eb1', &['\u0103', '\u0300']), ('\u1eb2', &['\u0102',
- '\u0309']), ('\u1eb3', &['\u0103', '\u0309']), ('\u1eb4', &['\u0102', '\u0303']), ('\u1eb5',
- &['\u0103', '\u0303']), ('\u1eb6', &['\u1ea0', '\u0306']), ('\u1eb7', &['\u1ea1',
- '\u0306']), ('\u1eb8', &['\x45', '\u0323']), ('\u1eb9', &['\x65', '\u0323']), ('\u1eba',
- &['\x45', '\u0309']), ('\u1ebb', &['\x65', '\u0309']), ('\u1ebc', &['\x45', '\u0303']),
- ('\u1ebd', &['\x65', '\u0303']), ('\u1ebe', &['\xca', '\u0301']), ('\u1ebf', &['\xea',
- '\u0301']), ('\u1ec0', &['\xca', '\u0300']), ('\u1ec1', &['\xea', '\u0300']), ('\u1ec2',
- &['\xca', '\u0309']), ('\u1ec3', &['\xea', '\u0309']), ('\u1ec4', &['\xca', '\u0303']),
- ('\u1ec5', &['\xea', '\u0303']), ('\u1ec6', &['\u1eb8', '\u0302']), ('\u1ec7', &['\u1eb9',
- '\u0302']), ('\u1ec8', &['\x49', '\u0309']), ('\u1ec9', &['\x69', '\u0309']), ('\u1eca',
- &['\x49', '\u0323']), ('\u1ecb', &['\x69', '\u0323']), ('\u1ecc', &['\x4f', '\u0323']),
- ('\u1ecd', &['\x6f', '\u0323']), ('\u1ece', &['\x4f', '\u0309']), ('\u1ecf', &['\x6f',
- '\u0309']), ('\u1ed0', &['\xd4', '\u0301']), ('\u1ed1', &['\xf4', '\u0301']), ('\u1ed2',
- &['\xd4', '\u0300']), ('\u1ed3', &['\xf4', '\u0300']), ('\u1ed4', &['\xd4', '\u0309']),
- ('\u1ed5', &['\xf4', '\u0309']), ('\u1ed6', &['\xd4', '\u0303']), ('\u1ed7', &['\xf4',
- '\u0303']), ('\u1ed8', &['\u1ecc', '\u0302']), ('\u1ed9', &['\u1ecd', '\u0302']), ('\u1eda',
- &['\u01a0', '\u0301']), ('\u1edb', &['\u01a1', '\u0301']), ('\u1edc', &['\u01a0',
- '\u0300']), ('\u1edd', &['\u01a1', '\u0300']), ('\u1ede', &['\u01a0', '\u0309']), ('\u1edf',
- &['\u01a1', '\u0309']), ('\u1ee0', &['\u01a0', '\u0303']), ('\u1ee1', &['\u01a1',
- '\u0303']), ('\u1ee2', &['\u01a0', '\u0323']), ('\u1ee3', &['\u01a1', '\u0323']), ('\u1ee4',
- &['\x55', '\u0323']), ('\u1ee5', &['\x75', '\u0323']), ('\u1ee6', &['\x55', '\u0309']),
- ('\u1ee7', &['\x75', '\u0309']), ('\u1ee8', &['\u01af', '\u0301']), ('\u1ee9', &['\u01b0',
- '\u0301']), ('\u1eea', &['\u01af', '\u0300']), ('\u1eeb', &['\u01b0', '\u0300']), ('\u1eec',
- &['\u01af', '\u0309']), ('\u1eed', &['\u01b0', '\u0309']), ('\u1eee', &['\u01af',
- '\u0303']), ('\u1eef', &['\u01b0', '\u0303']), ('\u1ef0', &['\u01af', '\u0323']), ('\u1ef1',
- &['\u01b0', '\u0323']), ('\u1ef2', &['\x59', '\u0300']), ('\u1ef3', &['\x79', '\u0300']),
- ('\u1ef4', &['\x59', '\u0323']), ('\u1ef5', &['\x79', '\u0323']), ('\u1ef6', &['\x59',
- '\u0309']), ('\u1ef7', &['\x79', '\u0309']), ('\u1ef8', &['\x59', '\u0303']), ('\u1ef9',
- &['\x79', '\u0303']), ('\u1f00', &['\u03b1', '\u0313']), ('\u1f01', &['\u03b1', '\u0314']),
- ('\u1f02', &['\u1f00', '\u0300']), ('\u1f03', &['\u1f01', '\u0300']), ('\u1f04', &['\u1f00',
- '\u0301']), ('\u1f05', &['\u1f01', '\u0301']), ('\u1f06', &['\u1f00', '\u0342']), ('\u1f07',
- &['\u1f01', '\u0342']), ('\u1f08', &['\u0391', '\u0313']), ('\u1f09', &['\u0391',
- '\u0314']), ('\u1f0a', &['\u1f08', '\u0300']), ('\u1f0b', &['\u1f09', '\u0300']), ('\u1f0c',
- &['\u1f08', '\u0301']), ('\u1f0d', &['\u1f09', '\u0301']), ('\u1f0e', &['\u1f08',
- '\u0342']), ('\u1f0f', &['\u1f09', '\u0342']), ('\u1f10', &['\u03b5', '\u0313']), ('\u1f11',
- &['\u03b5', '\u0314']), ('\u1f12', &['\u1f10', '\u0300']), ('\u1f13', &['\u1f11',
- '\u0300']), ('\u1f14', &['\u1f10', '\u0301']), ('\u1f15', &['\u1f11', '\u0301']), ('\u1f18',
- &['\u0395', '\u0313']), ('\u1f19', &['\u0395', '\u0314']), ('\u1f1a', &['\u1f18',
- '\u0300']), ('\u1f1b', &['\u1f19', '\u0300']), ('\u1f1c', &['\u1f18', '\u0301']), ('\u1f1d',
- &['\u1f19', '\u0301']), ('\u1f20', &['\u03b7', '\u0313']), ('\u1f21', &['\u03b7',
- '\u0314']), ('\u1f22', &['\u1f20', '\u0300']), ('\u1f23', &['\u1f21', '\u0300']), ('\u1f24',
- &['\u1f20', '\u0301']), ('\u1f25', &['\u1f21', '\u0301']), ('\u1f26', &['\u1f20',
- '\u0342']), ('\u1f27', &['\u1f21', '\u0342']), ('\u1f28', &['\u0397', '\u0313']), ('\u1f29',
- &['\u0397', '\u0314']), ('\u1f2a', &['\u1f28', '\u0300']), ('\u1f2b', &['\u1f29',
- '\u0300']), ('\u1f2c', &['\u1f28', '\u0301']), ('\u1f2d', &['\u1f29', '\u0301']), ('\u1f2e',
- &['\u1f28', '\u0342']), ('\u1f2f', &['\u1f29', '\u0342']), ('\u1f30', &['\u03b9',
- '\u0313']), ('\u1f31', &['\u03b9', '\u0314']), ('\u1f32', &['\u1f30', '\u0300']), ('\u1f33',
- &['\u1f31', '\u0300']), ('\u1f34', &['\u1f30', '\u0301']), ('\u1f35', &['\u1f31',
- '\u0301']), ('\u1f36', &['\u1f30', '\u0342']), ('\u1f37', &['\u1f31', '\u0342']), ('\u1f38',
- &['\u0399', '\u0313']), ('\u1f39', &['\u0399', '\u0314']), ('\u1f3a', &['\u1f38',
- '\u0300']), ('\u1f3b', &['\u1f39', '\u0300']), ('\u1f3c', &['\u1f38', '\u0301']), ('\u1f3d',
- &['\u1f39', '\u0301']), ('\u1f3e', &['\u1f38', '\u0342']), ('\u1f3f', &['\u1f39',
- '\u0342']), ('\u1f40', &['\u03bf', '\u0313']), ('\u1f41', &['\u03bf', '\u0314']), ('\u1f42',
- &['\u1f40', '\u0300']), ('\u1f43', &['\u1f41', '\u0300']), ('\u1f44', &['\u1f40',
- '\u0301']), ('\u1f45', &['\u1f41', '\u0301']), ('\u1f48', &['\u039f', '\u0313']), ('\u1f49',
- &['\u039f', '\u0314']), ('\u1f4a', &['\u1f48', '\u0300']), ('\u1f4b', &['\u1f49',
- '\u0300']), ('\u1f4c', &['\u1f48', '\u0301']), ('\u1f4d', &['\u1f49', '\u0301']), ('\u1f50',
- &['\u03c5', '\u0313']), ('\u1f51', &['\u03c5', '\u0314']), ('\u1f52', &['\u1f50',
- '\u0300']), ('\u1f53', &['\u1f51', '\u0300']), ('\u1f54', &['\u1f50', '\u0301']), ('\u1f55',
- &['\u1f51', '\u0301']), ('\u1f56', &['\u1f50', '\u0342']), ('\u1f57', &['\u1f51',
- '\u0342']), ('\u1f59', &['\u03a5', '\u0314']), ('\u1f5b', &['\u1f59', '\u0300']), ('\u1f5d',
- &['\u1f59', '\u0301']), ('\u1f5f', &['\u1f59', '\u0342']), ('\u1f60', &['\u03c9',
- '\u0313']), ('\u1f61', &['\u03c9', '\u0314']), ('\u1f62', &['\u1f60', '\u0300']), ('\u1f63',
- &['\u1f61', '\u0300']), ('\u1f64', &['\u1f60', '\u0301']), ('\u1f65', &['\u1f61',
- '\u0301']), ('\u1f66', &['\u1f60', '\u0342']), ('\u1f67', &['\u1f61', '\u0342']), ('\u1f68',
- &['\u03a9', '\u0313']), ('\u1f69', &['\u03a9', '\u0314']), ('\u1f6a', &['\u1f68',
- '\u0300']), ('\u1f6b', &['\u1f69', '\u0300']), ('\u1f6c', &['\u1f68', '\u0301']), ('\u1f6d',
- &['\u1f69', '\u0301']), ('\u1f6e', &['\u1f68', '\u0342']), ('\u1f6f', &['\u1f69',
- '\u0342']), ('\u1f70', &['\u03b1', '\u0300']), ('\u1f71', &['\u03ac']), ('\u1f72',
- &['\u03b5', '\u0300']), ('\u1f73', &['\u03ad']), ('\u1f74', &['\u03b7', '\u0300']),
- ('\u1f75', &['\u03ae']), ('\u1f76', &['\u03b9', '\u0300']), ('\u1f77', &['\u03af']),
- ('\u1f78', &['\u03bf', '\u0300']), ('\u1f79', &['\u03cc']), ('\u1f7a', &['\u03c5',
- '\u0300']), ('\u1f7b', &['\u03cd']), ('\u1f7c', &['\u03c9', '\u0300']), ('\u1f7d',
- &['\u03ce']), ('\u1f80', &['\u1f00', '\u0345']), ('\u1f81', &['\u1f01', '\u0345']),
- ('\u1f82', &['\u1f02', '\u0345']), ('\u1f83', &['\u1f03', '\u0345']), ('\u1f84', &['\u1f04',
- '\u0345']), ('\u1f85', &['\u1f05', '\u0345']), ('\u1f86', &['\u1f06', '\u0345']), ('\u1f87',
- &['\u1f07', '\u0345']), ('\u1f88', &['\u1f08', '\u0345']), ('\u1f89', &['\u1f09',
- '\u0345']), ('\u1f8a', &['\u1f0a', '\u0345']), ('\u1f8b', &['\u1f0b', '\u0345']), ('\u1f8c',
- &['\u1f0c', '\u0345']), ('\u1f8d', &['\u1f0d', '\u0345']), ('\u1f8e', &['\u1f0e',
- '\u0345']), ('\u1f8f', &['\u1f0f', '\u0345']), ('\u1f90', &['\u1f20', '\u0345']), ('\u1f91',
- &['\u1f21', '\u0345']), ('\u1f92', &['\u1f22', '\u0345']), ('\u1f93', &['\u1f23',
- '\u0345']), ('\u1f94', &['\u1f24', '\u0345']), ('\u1f95', &['\u1f25', '\u0345']), ('\u1f96',
- &['\u1f26', '\u0345']), ('\u1f97', &['\u1f27', '\u0345']), ('\u1f98', &['\u1f28',
- '\u0345']), ('\u1f99', &['\u1f29', '\u0345']), ('\u1f9a', &['\u1f2a', '\u0345']), ('\u1f9b',
- &['\u1f2b', '\u0345']), ('\u1f9c', &['\u1f2c', '\u0345']), ('\u1f9d', &['\u1f2d',
- '\u0345']), ('\u1f9e', &['\u1f2e', '\u0345']), ('\u1f9f', &['\u1f2f', '\u0345']), ('\u1fa0',
- &['\u1f60', '\u0345']), ('\u1fa1', &['\u1f61', '\u0345']), ('\u1fa2', &['\u1f62',
- '\u0345']), ('\u1fa3', &['\u1f63', '\u0345']), ('\u1fa4', &['\u1f64', '\u0345']), ('\u1fa5',
- &['\u1f65', '\u0345']), ('\u1fa6', &['\u1f66', '\u0345']), ('\u1fa7', &['\u1f67',
- '\u0345']), ('\u1fa8', &['\u1f68', '\u0345']), ('\u1fa9', &['\u1f69', '\u0345']), ('\u1faa',
- &['\u1f6a', '\u0345']), ('\u1fab', &['\u1f6b', '\u0345']), ('\u1fac', &['\u1f6c',
- '\u0345']), ('\u1fad', &['\u1f6d', '\u0345']), ('\u1fae', &['\u1f6e', '\u0345']), ('\u1faf',
- &['\u1f6f', '\u0345']), ('\u1fb0', &['\u03b1', '\u0306']), ('\u1fb1', &['\u03b1',
- '\u0304']), ('\u1fb2', &['\u1f70', '\u0345']), ('\u1fb3', &['\u03b1', '\u0345']), ('\u1fb4',
- &['\u03ac', '\u0345']), ('\u1fb6', &['\u03b1', '\u0342']), ('\u1fb7', &['\u1fb6',
- '\u0345']), ('\u1fb8', &['\u0391', '\u0306']), ('\u1fb9', &['\u0391', '\u0304']), ('\u1fba',
- &['\u0391', '\u0300']), ('\u1fbb', &['\u0386']), ('\u1fbc', &['\u0391', '\u0345']),
- ('\u1fbe', &['\u03b9']), ('\u1fc1', &['\xa8', '\u0342']), ('\u1fc2', &['\u1f74', '\u0345']),
- ('\u1fc3', &['\u03b7', '\u0345']), ('\u1fc4', &['\u03ae', '\u0345']), ('\u1fc6', &['\u03b7',
- '\u0342']), ('\u1fc7', &['\u1fc6', '\u0345']), ('\u1fc8', &['\u0395', '\u0300']), ('\u1fc9',
- &['\u0388']), ('\u1fca', &['\u0397', '\u0300']), ('\u1fcb', &['\u0389']), ('\u1fcc',
- &['\u0397', '\u0345']), ('\u1fcd', &['\u1fbf', '\u0300']), ('\u1fce', &['\u1fbf',
- '\u0301']), ('\u1fcf', &['\u1fbf', '\u0342']), ('\u1fd0', &['\u03b9', '\u0306']), ('\u1fd1',
- &['\u03b9', '\u0304']), ('\u1fd2', &['\u03ca', '\u0300']), ('\u1fd3', &['\u0390']),
- ('\u1fd6', &['\u03b9', '\u0342']), ('\u1fd7', &['\u03ca', '\u0342']), ('\u1fd8', &['\u0399',
- '\u0306']), ('\u1fd9', &['\u0399', '\u0304']), ('\u1fda', &['\u0399', '\u0300']), ('\u1fdb',
- &['\u038a']), ('\u1fdd', &['\u1ffe', '\u0300']), ('\u1fde', &['\u1ffe', '\u0301']),
- ('\u1fdf', &['\u1ffe', '\u0342']), ('\u1fe0', &['\u03c5', '\u0306']), ('\u1fe1', &['\u03c5',
- '\u0304']), ('\u1fe2', &['\u03cb', '\u0300']), ('\u1fe3', &['\u03b0']), ('\u1fe4',
- &['\u03c1', '\u0313']), ('\u1fe5', &['\u03c1', '\u0314']), ('\u1fe6', &['\u03c5',
- '\u0342']), ('\u1fe7', &['\u03cb', '\u0342']), ('\u1fe8', &['\u03a5', '\u0306']), ('\u1fe9',
- &['\u03a5', '\u0304']), ('\u1fea', &['\u03a5', '\u0300']), ('\u1feb', &['\u038e']),
- ('\u1fec', &['\u03a1', '\u0314']), ('\u1fed', &['\xa8', '\u0300']), ('\u1fee', &['\u0385']),
- ('\u1fef', &['\x60']), ('\u1ff2', &['\u1f7c', '\u0345']), ('\u1ff3', &['\u03c9', '\u0345']),
- ('\u1ff4', &['\u03ce', '\u0345']), ('\u1ff6', &['\u03c9', '\u0342']), ('\u1ff7', &['\u1ff6',
- '\u0345']), ('\u1ff8', &['\u039f', '\u0300']), ('\u1ff9', &['\u038c']), ('\u1ffa',
- &['\u03a9', '\u0300']), ('\u1ffb', &['\u038f']), ('\u1ffc', &['\u03a9', '\u0345']),
- ('\u1ffd', &['\xb4']), ('\u2000', &['\u2002']), ('\u2001', &['\u2003']), ('\u2126',
- &['\u03a9']), ('\u212a', &['\x4b']), ('\u212b', &['\xc5']), ('\u219a', &['\u2190',
- '\u0338']), ('\u219b', &['\u2192', '\u0338']), ('\u21ae', &['\u2194', '\u0338']), ('\u21cd',
- &['\u21d0', '\u0338']), ('\u21ce', &['\u21d4', '\u0338']), ('\u21cf', &['\u21d2',
- '\u0338']), ('\u2204', &['\u2203', '\u0338']), ('\u2209', &['\u2208', '\u0338']), ('\u220c',
- &['\u220b', '\u0338']), ('\u2224', &['\u2223', '\u0338']), ('\u2226', &['\u2225',
- '\u0338']), ('\u2241', &['\u223c', '\u0338']), ('\u2244', &['\u2243', '\u0338']), ('\u2247',
- &['\u2245', '\u0338']), ('\u2249', &['\u2248', '\u0338']), ('\u2260', &['\x3d', '\u0338']),
- ('\u2262', &['\u2261', '\u0338']), ('\u226d', &['\u224d', '\u0338']), ('\u226e', &['\x3c',
- '\u0338']), ('\u226f', &['\x3e', '\u0338']), ('\u2270', &['\u2264', '\u0338']), ('\u2271',
- &['\u2265', '\u0338']), ('\u2274', &['\u2272', '\u0338']), ('\u2275', &['\u2273',
- '\u0338']), ('\u2278', &['\u2276', '\u0338']), ('\u2279', &['\u2277', '\u0338']), ('\u2280',
- &['\u227a', '\u0338']), ('\u2281', &['\u227b', '\u0338']), ('\u2284', &['\u2282',
- '\u0338']), ('\u2285', &['\u2283', '\u0338']), ('\u2288', &['\u2286', '\u0338']), ('\u2289',
- &['\u2287', '\u0338']), ('\u22ac', &['\u22a2', '\u0338']), ('\u22ad', &['\u22a8',
- '\u0338']), ('\u22ae', &['\u22a9', '\u0338']), ('\u22af', &['\u22ab', '\u0338']), ('\u22e0',
- &['\u227c', '\u0338']), ('\u22e1', &['\u227d', '\u0338']), ('\u22e2', &['\u2291',
- '\u0338']), ('\u22e3', &['\u2292', '\u0338']), ('\u22ea', &['\u22b2', '\u0338']), ('\u22eb',
- &['\u22b3', '\u0338']), ('\u22ec', &['\u22b4', '\u0338']), ('\u22ed', &['\u22b5',
- '\u0338']), ('\u2329', &['\u3008']), ('\u232a', &['\u3009']), ('\u2adc', &['\u2add',
- '\u0338']), ('\u304c', &['\u304b', '\u3099']), ('\u304e', &['\u304d', '\u3099']), ('\u3050',
- &['\u304f', '\u3099']), ('\u3052', &['\u3051', '\u3099']), ('\u3054', &['\u3053',
- '\u3099']), ('\u3056', &['\u3055', '\u3099']), ('\u3058', &['\u3057', '\u3099']), ('\u305a',
- &['\u3059', '\u3099']), ('\u305c', &['\u305b', '\u3099']), ('\u305e', &['\u305d',
- '\u3099']), ('\u3060', &['\u305f', '\u3099']), ('\u3062', &['\u3061', '\u3099']), ('\u3065',
- &['\u3064', '\u3099']), ('\u3067', &['\u3066', '\u3099']), ('\u3069', &['\u3068',
- '\u3099']), ('\u3070', &['\u306f', '\u3099']), ('\u3071', &['\u306f', '\u309a']), ('\u3073',
- &['\u3072', '\u3099']), ('\u3074', &['\u3072', '\u309a']), ('\u3076', &['\u3075',
- '\u3099']), ('\u3077', &['\u3075', '\u309a']), ('\u3079', &['\u3078', '\u3099']), ('\u307a',
- &['\u3078', '\u309a']), ('\u307c', &['\u307b', '\u3099']), ('\u307d', &['\u307b',
- '\u309a']), ('\u3094', &['\u3046', '\u3099']), ('\u309e', &['\u309d', '\u3099']), ('\u30ac',
- &['\u30ab', '\u3099']), ('\u30ae', &['\u30ad', '\u3099']), ('\u30b0', &['\u30af',
- '\u3099']), ('\u30b2', &['\u30b1', '\u3099']), ('\u30b4', &['\u30b3', '\u3099']), ('\u30b6',
- &['\u30b5', '\u3099']), ('\u30b8', &['\u30b7', '\u3099']), ('\u30ba', &['\u30b9',
- '\u3099']), ('\u30bc', &['\u30bb', '\u3099']), ('\u30be', &['\u30bd', '\u3099']), ('\u30c0',
- &['\u30bf', '\u3099']), ('\u30c2', &['\u30c1', '\u3099']), ('\u30c5', &['\u30c4',
- '\u3099']), ('\u30c7', &['\u30c6', '\u3099']), ('\u30c9', &['\u30c8', '\u3099']), ('\u30d0',
- &['\u30cf', '\u3099']), ('\u30d1', &['\u30cf', '\u309a']), ('\u30d3', &['\u30d2',
- '\u3099']), ('\u30d4', &['\u30d2', '\u309a']), ('\u30d6', &['\u30d5', '\u3099']), ('\u30d7',
- &['\u30d5', '\u309a']), ('\u30d9', &['\u30d8', '\u3099']), ('\u30da', &['\u30d8',
- '\u309a']), ('\u30dc', &['\u30db', '\u3099']), ('\u30dd', &['\u30db', '\u309a']), ('\u30f4',
- &['\u30a6', '\u3099']), ('\u30f7', &['\u30ef', '\u3099']), ('\u30f8', &['\u30f0',
- '\u3099']), ('\u30f9', &['\u30f1', '\u3099']), ('\u30fa', &['\u30f2', '\u3099']), ('\u30fe',
- &['\u30fd', '\u3099']), ('\uf900', &['\u8c48']), ('\uf901', &['\u66f4']), ('\uf902',
- &['\u8eca']), ('\uf903', &['\u8cc8']), ('\uf904', &['\u6ed1']), ('\uf905', &['\u4e32']),
- ('\uf906', &['\u53e5']), ('\uf907', &['\u9f9c']), ('\uf908', &['\u9f9c']), ('\uf909',
- &['\u5951']), ('\uf90a', &['\u91d1']), ('\uf90b', &['\u5587']), ('\uf90c', &['\u5948']),
- ('\uf90d', &['\u61f6']), ('\uf90e', &['\u7669']), ('\uf90f', &['\u7f85']), ('\uf910',
- &['\u863f']), ('\uf911', &['\u87ba']), ('\uf912', &['\u88f8']), ('\uf913', &['\u908f']),
- ('\uf914', &['\u6a02']), ('\uf915', &['\u6d1b']), ('\uf916', &['\u70d9']), ('\uf917',
- &['\u73de']), ('\uf918', &['\u843d']), ('\uf919', &['\u916a']), ('\uf91a', &['\u99f1']),
- ('\uf91b', &['\u4e82']), ('\uf91c', &['\u5375']), ('\uf91d', &['\u6b04']), ('\uf91e',
- &['\u721b']), ('\uf91f', &['\u862d']), ('\uf920', &['\u9e1e']), ('\uf921', &['\u5d50']),
- ('\uf922', &['\u6feb']), ('\uf923', &['\u85cd']), ('\uf924', &['\u8964']), ('\uf925',
- &['\u62c9']), ('\uf926', &['\u81d8']), ('\uf927', &['\u881f']), ('\uf928', &['\u5eca']),
- ('\uf929', &['\u6717']), ('\uf92a', &['\u6d6a']), ('\uf92b', &['\u72fc']), ('\uf92c',
- &['\u90ce']), ('\uf92d', &['\u4f86']), ('\uf92e', &['\u51b7']), ('\uf92f', &['\u52de']),
- ('\uf930', &['\u64c4']), ('\uf931', &['\u6ad3']), ('\uf932', &['\u7210']), ('\uf933',
- &['\u76e7']), ('\uf934', &['\u8001']), ('\uf935', &['\u8606']), ('\uf936', &['\u865c']),
- ('\uf937', &['\u8def']), ('\uf938', &['\u9732']), ('\uf939', &['\u9b6f']), ('\uf93a',
- &['\u9dfa']), ('\uf93b', &['\u788c']), ('\uf93c', &['\u797f']), ('\uf93d', &['\u7da0']),
- ('\uf93e', &['\u83c9']), ('\uf93f', &['\u9304']), ('\uf940', &['\u9e7f']), ('\uf941',
- &['\u8ad6']), ('\uf942', &['\u58df']), ('\uf943', &['\u5f04']), ('\uf944', &['\u7c60']),
- ('\uf945', &['\u807e']), ('\uf946', &['\u7262']), ('\uf947', &['\u78ca']), ('\uf948',
- &['\u8cc2']), ('\uf949', &['\u96f7']), ('\uf94a', &['\u58d8']), ('\uf94b', &['\u5c62']),
- ('\uf94c', &['\u6a13']), ('\uf94d', &['\u6dda']), ('\uf94e', &['\u6f0f']), ('\uf94f',
- &['\u7d2f']), ('\uf950', &['\u7e37']), ('\uf951', &['\u964b']), ('\uf952', &['\u52d2']),
- ('\uf953', &['\u808b']), ('\uf954', &['\u51dc']), ('\uf955', &['\u51cc']), ('\uf956',
- &['\u7a1c']), ('\uf957', &['\u7dbe']), ('\uf958', &['\u83f1']), ('\uf959', &['\u9675']),
- ('\uf95a', &['\u8b80']), ('\uf95b', &['\u62cf']), ('\uf95c', &['\u6a02']), ('\uf95d',
- &['\u8afe']), ('\uf95e', &['\u4e39']), ('\uf95f', &['\u5be7']), ('\uf960', &['\u6012']),
- ('\uf961', &['\u7387']), ('\uf962', &['\u7570']), ('\uf963', &['\u5317']), ('\uf964',
- &['\u78fb']), ('\uf965', &['\u4fbf']), ('\uf966', &['\u5fa9']), ('\uf967', &['\u4e0d']),
- ('\uf968', &['\u6ccc']), ('\uf969', &['\u6578']), ('\uf96a', &['\u7d22']), ('\uf96b',
- &['\u53c3']), ('\uf96c', &['\u585e']), ('\uf96d', &['\u7701']), ('\uf96e', &['\u8449']),
- ('\uf96f', &['\u8aaa']), ('\uf970', &['\u6bba']), ('\uf971', &['\u8fb0']), ('\uf972',
- &['\u6c88']), ('\uf973', &['\u62fe']), ('\uf974', &['\u82e5']), ('\uf975', &['\u63a0']),
- ('\uf976', &['\u7565']), ('\uf977', &['\u4eae']), ('\uf978', &['\u5169']), ('\uf979',
- &['\u51c9']), ('\uf97a', &['\u6881']), ('\uf97b', &['\u7ce7']), ('\uf97c', &['\u826f']),
- ('\uf97d', &['\u8ad2']), ('\uf97e', &['\u91cf']), ('\uf97f', &['\u52f5']), ('\uf980',
- &['\u5442']), ('\uf981', &['\u5973']), ('\uf982', &['\u5eec']), ('\uf983', &['\u65c5']),
- ('\uf984', &['\u6ffe']), ('\uf985', &['\u792a']), ('\uf986', &['\u95ad']), ('\uf987',
- &['\u9a6a']), ('\uf988', &['\u9e97']), ('\uf989', &['\u9ece']), ('\uf98a', &['\u529b']),
- ('\uf98b', &['\u66c6']), ('\uf98c', &['\u6b77']), ('\uf98d', &['\u8f62']), ('\uf98e',
- &['\u5e74']), ('\uf98f', &['\u6190']), ('\uf990', &['\u6200']), ('\uf991', &['\u649a']),
- ('\uf992', &['\u6f23']), ('\uf993', &['\u7149']), ('\uf994', &['\u7489']), ('\uf995',
- &['\u79ca']), ('\uf996', &['\u7df4']), ('\uf997', &['\u806f']), ('\uf998', &['\u8f26']),
- ('\uf999', &['\u84ee']), ('\uf99a', &['\u9023']), ('\uf99b', &['\u934a']), ('\uf99c',
- &['\u5217']), ('\uf99d', &['\u52a3']), ('\uf99e', &['\u54bd']), ('\uf99f', &['\u70c8']),
- ('\uf9a0', &['\u88c2']), ('\uf9a1', &['\u8aaa']), ('\uf9a2', &['\u5ec9']), ('\uf9a3',
- &['\u5ff5']), ('\uf9a4', &['\u637b']), ('\uf9a5', &['\u6bae']), ('\uf9a6', &['\u7c3e']),
- ('\uf9a7', &['\u7375']), ('\uf9a8', &['\u4ee4']), ('\uf9a9', &['\u56f9']), ('\uf9aa',
- &['\u5be7']), ('\uf9ab', &['\u5dba']), ('\uf9ac', &['\u601c']), ('\uf9ad', &['\u73b2']),
- ('\uf9ae', &['\u7469']), ('\uf9af', &['\u7f9a']), ('\uf9b0', &['\u8046']), ('\uf9b1',
- &['\u9234']), ('\uf9b2', &['\u96f6']), ('\uf9b3', &['\u9748']), ('\uf9b4', &['\u9818']),
- ('\uf9b5', &['\u4f8b']), ('\uf9b6', &['\u79ae']), ('\uf9b7', &['\u91b4']), ('\uf9b8',
- &['\u96b8']), ('\uf9b9', &['\u60e1']), ('\uf9ba', &['\u4e86']), ('\uf9bb', &['\u50da']),
- ('\uf9bc', &['\u5bee']), ('\uf9bd', &['\u5c3f']), ('\uf9be', &['\u6599']), ('\uf9bf',
- &['\u6a02']), ('\uf9c0', &['\u71ce']), ('\uf9c1', &['\u7642']), ('\uf9c2', &['\u84fc']),
- ('\uf9c3', &['\u907c']), ('\uf9c4', &['\u9f8d']), ('\uf9c5', &['\u6688']), ('\uf9c6',
- &['\u962e']), ('\uf9c7', &['\u5289']), ('\uf9c8', &['\u677b']), ('\uf9c9', &['\u67f3']),
- ('\uf9ca', &['\u6d41']), ('\uf9cb', &['\u6e9c']), ('\uf9cc', &['\u7409']), ('\uf9cd',
- &['\u7559']), ('\uf9ce', &['\u786b']), ('\uf9cf', &['\u7d10']), ('\uf9d0', &['\u985e']),
- ('\uf9d1', &['\u516d']), ('\uf9d2', &['\u622e']), ('\uf9d3', &['\u9678']), ('\uf9d4',
- &['\u502b']), ('\uf9d5', &['\u5d19']), ('\uf9d6', &['\u6dea']), ('\uf9d7', &['\u8f2a']),
- ('\uf9d8', &['\u5f8b']), ('\uf9d9', &['\u6144']), ('\uf9da', &['\u6817']), ('\uf9db',
- &['\u7387']), ('\uf9dc', &['\u9686']), ('\uf9dd', &['\u5229']), ('\uf9de', &['\u540f']),
- ('\uf9df', &['\u5c65']), ('\uf9e0', &['\u6613']), ('\uf9e1', &['\u674e']), ('\uf9e2',
- &['\u68a8']), ('\uf9e3', &['\u6ce5']), ('\uf9e4', &['\u7406']), ('\uf9e5', &['\u75e2']),
- ('\uf9e6', &['\u7f79']), ('\uf9e7', &['\u88cf']), ('\uf9e8', &['\u88e1']), ('\uf9e9',
- &['\u91cc']), ('\uf9ea', &['\u96e2']), ('\uf9eb', &['\u533f']), ('\uf9ec', &['\u6eba']),
- ('\uf9ed', &['\u541d']), ('\uf9ee', &['\u71d0']), ('\uf9ef', &['\u7498']), ('\uf9f0',
- &['\u85fa']), ('\uf9f1', &['\u96a3']), ('\uf9f2', &['\u9c57']), ('\uf9f3', &['\u9e9f']),
- ('\uf9f4', &['\u6797']), ('\uf9f5', &['\u6dcb']), ('\uf9f6', &['\u81e8']), ('\uf9f7',
- &['\u7acb']), ('\uf9f8', &['\u7b20']), ('\uf9f9', &['\u7c92']), ('\uf9fa', &['\u72c0']),
- ('\uf9fb', &['\u7099']), ('\uf9fc', &['\u8b58']), ('\uf9fd', &['\u4ec0']), ('\uf9fe',
- &['\u8336']), ('\uf9ff', &['\u523a']), ('\ufa00', &['\u5207']), ('\ufa01', &['\u5ea6']),
- ('\ufa02', &['\u62d3']), ('\ufa03', &['\u7cd6']), ('\ufa04', &['\u5b85']), ('\ufa05',
- &['\u6d1e']), ('\ufa06', &['\u66b4']), ('\ufa07', &['\u8f3b']), ('\ufa08', &['\u884c']),
- ('\ufa09', &['\u964d']), ('\ufa0a', &['\u898b']), ('\ufa0b', &['\u5ed3']), ('\ufa0c',
- &['\u5140']), ('\ufa0d', &['\u55c0']), ('\ufa10', &['\u585a']), ('\ufa12', &['\u6674']),
- ('\ufa15', &['\u51de']), ('\ufa16', &['\u732a']), ('\ufa17', &['\u76ca']), ('\ufa18',
- &['\u793c']), ('\ufa19', &['\u795e']), ('\ufa1a', &['\u7965']), ('\ufa1b', &['\u798f']),
- ('\ufa1c', &['\u9756']), ('\ufa1d', &['\u7cbe']), ('\ufa1e', &['\u7fbd']), ('\ufa20',
- &['\u8612']), ('\ufa22', &['\u8af8']), ('\ufa25', &['\u9038']), ('\ufa26', &['\u90fd']),
- ('\ufa2a', &['\u98ef']), ('\ufa2b', &['\u98fc']), ('\ufa2c', &['\u9928']), ('\ufa2d',
- &['\u9db4']), ('\ufa2e', &['\u90de']), ('\ufa2f', &['\u96b7']), ('\ufa30', &['\u4fae']),
- ('\ufa31', &['\u50e7']), ('\ufa32', &['\u514d']), ('\ufa33', &['\u52c9']), ('\ufa34',
- &['\u52e4']), ('\ufa35', &['\u5351']), ('\ufa36', &['\u559d']), ('\ufa37', &['\u5606']),
- ('\ufa38', &['\u5668']), ('\ufa39', &['\u5840']), ('\ufa3a', &['\u58a8']), ('\ufa3b',
- &['\u5c64']), ('\ufa3c', &['\u5c6e']), ('\ufa3d', &['\u6094']), ('\ufa3e', &['\u6168']),
- ('\ufa3f', &['\u618e']), ('\ufa40', &['\u61f2']), ('\ufa41', &['\u654f']), ('\ufa42',
- &['\u65e2']), ('\ufa43', &['\u6691']), ('\ufa44', &['\u6885']), ('\ufa45', &['\u6d77']),
- ('\ufa46', &['\u6e1a']), ('\ufa47', &['\u6f22']), ('\ufa48', &['\u716e']), ('\ufa49',
- &['\u722b']), ('\ufa4a', &['\u7422']), ('\ufa4b', &['\u7891']), ('\ufa4c', &['\u793e']),
- ('\ufa4d', &['\u7949']), ('\ufa4e', &['\u7948']), ('\ufa4f', &['\u7950']), ('\ufa50',
- &['\u7956']), ('\ufa51', &['\u795d']), ('\ufa52', &['\u798d']), ('\ufa53', &['\u798e']),
- ('\ufa54', &['\u7a40']), ('\ufa55', &['\u7a81']), ('\ufa56', &['\u7bc0']), ('\ufa57',
- &['\u7df4']), ('\ufa58', &['\u7e09']), ('\ufa59', &['\u7e41']), ('\ufa5a', &['\u7f72']),
- ('\ufa5b', &['\u8005']), ('\ufa5c', &['\u81ed']), ('\ufa5d', &['\u8279']), ('\ufa5e',
- &['\u8279']), ('\ufa5f', &['\u8457']), ('\ufa60', &['\u8910']), ('\ufa61', &['\u8996']),
- ('\ufa62', &['\u8b01']), ('\ufa63', &['\u8b39']), ('\ufa64', &['\u8cd3']), ('\ufa65',
- &['\u8d08']), ('\ufa66', &['\u8fb6']), ('\ufa67', &['\u9038']), ('\ufa68', &['\u96e3']),
- ('\ufa69', &['\u97ff']), ('\ufa6a', &['\u983b']), ('\ufa6b', &['\u6075']), ('\ufa6c',
- &['\U000242ee']), ('\ufa6d', &['\u8218']), ('\ufa70', &['\u4e26']), ('\ufa71', &['\u51b5']),
- ('\ufa72', &['\u5168']), ('\ufa73', &['\u4f80']), ('\ufa74', &['\u5145']), ('\ufa75',
- &['\u5180']), ('\ufa76', &['\u52c7']), ('\ufa77', &['\u52fa']), ('\ufa78', &['\u559d']),
- ('\ufa79', &['\u5555']), ('\ufa7a', &['\u5599']), ('\ufa7b', &['\u55e2']), ('\ufa7c',
- &['\u585a']), ('\ufa7d', &['\u58b3']), ('\ufa7e', &['\u5944']), ('\ufa7f', &['\u5954']),
- ('\ufa80', &['\u5a62']), ('\ufa81', &['\u5b28']), ('\ufa82', &['\u5ed2']), ('\ufa83',
- &['\u5ed9']), ('\ufa84', &['\u5f69']), ('\ufa85', &['\u5fad']), ('\ufa86', &['\u60d8']),
- ('\ufa87', &['\u614e']), ('\ufa88', &['\u6108']), ('\ufa89', &['\u618e']), ('\ufa8a',
- &['\u6160']), ('\ufa8b', &['\u61f2']), ('\ufa8c', &['\u6234']), ('\ufa8d', &['\u63c4']),
- ('\ufa8e', &['\u641c']), ('\ufa8f', &['\u6452']), ('\ufa90', &['\u6556']), ('\ufa91',
- &['\u6674']), ('\ufa92', &['\u6717']), ('\ufa93', &['\u671b']), ('\ufa94', &['\u6756']),
- ('\ufa95', &['\u6b79']), ('\ufa96', &['\u6bba']), ('\ufa97', &['\u6d41']), ('\ufa98',
- &['\u6edb']), ('\ufa99', &['\u6ecb']), ('\ufa9a', &['\u6f22']), ('\ufa9b', &['\u701e']),
- ('\ufa9c', &['\u716e']), ('\ufa9d', &['\u77a7']), ('\ufa9e', &['\u7235']), ('\ufa9f',
- &['\u72af']), ('\ufaa0', &['\u732a']), ('\ufaa1', &['\u7471']), ('\ufaa2', &['\u7506']),
- ('\ufaa3', &['\u753b']), ('\ufaa4', &['\u761d']), ('\ufaa5', &['\u761f']), ('\ufaa6',
- &['\u76ca']), ('\ufaa7', &['\u76db']), ('\ufaa8', &['\u76f4']), ('\ufaa9', &['\u774a']),
- ('\ufaaa', &['\u7740']), ('\ufaab', &['\u78cc']), ('\ufaac', &['\u7ab1']), ('\ufaad',
- &['\u7bc0']), ('\ufaae', &['\u7c7b']), ('\ufaaf', &['\u7d5b']), ('\ufab0', &['\u7df4']),
- ('\ufab1', &['\u7f3e']), ('\ufab2', &['\u8005']), ('\ufab3', &['\u8352']), ('\ufab4',
- &['\u83ef']), ('\ufab5', &['\u8779']), ('\ufab6', &['\u8941']), ('\ufab7', &['\u8986']),
- ('\ufab8', &['\u8996']), ('\ufab9', &['\u8abf']), ('\ufaba', &['\u8af8']), ('\ufabb',
- &['\u8acb']), ('\ufabc', &['\u8b01']), ('\ufabd', &['\u8afe']), ('\ufabe', &['\u8aed']),
- ('\ufabf', &['\u8b39']), ('\ufac0', &['\u8b8a']), ('\ufac1', &['\u8d08']), ('\ufac2',
- &['\u8f38']), ('\ufac3', &['\u9072']), ('\ufac4', &['\u9199']), ('\ufac5', &['\u9276']),
- ('\ufac6', &['\u967c']), ('\ufac7', &['\u96e3']), ('\ufac8', &['\u9756']), ('\ufac9',
- &['\u97db']), ('\ufaca', &['\u97ff']), ('\ufacb', &['\u980b']), ('\ufacc', &['\u983b']),
- ('\ufacd', &['\u9b12']), ('\uface', &['\u9f9c']), ('\ufacf', &['\U0002284a']), ('\ufad0',
- &['\U00022844']), ('\ufad1', &['\U000233d5']), ('\ufad2', &['\u3b9d']), ('\ufad3',
- &['\u4018']), ('\ufad4', &['\u4039']), ('\ufad5', &['\U00025249']), ('\ufad6',
- &['\U00025cd0']), ('\ufad7', &['\U00027ed3']), ('\ufad8', &['\u9f43']), ('\ufad9',
- &['\u9f8e']), ('\ufb1d', &['\u05d9', '\u05b4']), ('\ufb1f', &['\u05f2', '\u05b7']),
- ('\ufb2a', &['\u05e9', '\u05c1']), ('\ufb2b', &['\u05e9', '\u05c2']), ('\ufb2c', &['\ufb49',
- '\u05c1']), ('\ufb2d', &['\ufb49', '\u05c2']), ('\ufb2e', &['\u05d0', '\u05b7']), ('\ufb2f',
- &['\u05d0', '\u05b8']), ('\ufb30', &['\u05d0', '\u05bc']), ('\ufb31', &['\u05d1',
- '\u05bc']), ('\ufb32', &['\u05d2', '\u05bc']), ('\ufb33', &['\u05d3', '\u05bc']), ('\ufb34',
- &['\u05d4', '\u05bc']), ('\ufb35', &['\u05d5', '\u05bc']), ('\ufb36', &['\u05d6',
- '\u05bc']), ('\ufb38', &['\u05d8', '\u05bc']), ('\ufb39', &['\u05d9', '\u05bc']), ('\ufb3a',
- &['\u05da', '\u05bc']), ('\ufb3b', &['\u05db', '\u05bc']), ('\ufb3c', &['\u05dc',
- '\u05bc']), ('\ufb3e', &['\u05de', '\u05bc']), ('\ufb40', &['\u05e0', '\u05bc']), ('\ufb41',
- &['\u05e1', '\u05bc']), ('\ufb43', &['\u05e3', '\u05bc']), ('\ufb44', &['\u05e4',
- '\u05bc']), ('\ufb46', &['\u05e6', '\u05bc']), ('\ufb47', &['\u05e7', '\u05bc']), ('\ufb48',
- &['\u05e8', '\u05bc']), ('\ufb49', &['\u05e9', '\u05bc']), ('\ufb4a', &['\u05ea',
- '\u05bc']), ('\ufb4b', &['\u05d5', '\u05b9']), ('\ufb4c', &['\u05d1', '\u05bf']), ('\ufb4d',
- &['\u05db', '\u05bf']), ('\ufb4e', &['\u05e4', '\u05bf']), ('\U0001109a', &['\U00011099',
- '\U000110ba']), ('\U0001109c', &['\U0001109b', '\U000110ba']), ('\U000110ab',
- &['\U000110a5', '\U000110ba']), ('\U0001112e', &['\U00011131', '\U00011127']),
- ('\U0001112f', &['\U00011132', '\U00011127']), ('\U0001d15e', &['\U0001d157',
- '\U0001d165']), ('\U0001d15f', &['\U0001d158', '\U0001d165']), ('\U0001d160',
- &['\U0001d15f', '\U0001d16e']), ('\U0001d161', &['\U0001d15f', '\U0001d16f']),
- ('\U0001d162', &['\U0001d15f', '\U0001d170']), ('\U0001d163', &['\U0001d15f',
- '\U0001d171']), ('\U0001d164', &['\U0001d15f', '\U0001d172']), ('\U0001d1bb',
- &['\U0001d1b9', '\U0001d165']), ('\U0001d1bc', &['\U0001d1ba', '\U0001d165']),
- ('\U0001d1bd', &['\U0001d1bb', '\U0001d16e']), ('\U0001d1be', &['\U0001d1bc',
- '\U0001d16e']), ('\U0001d1bf', &['\U0001d1bb', '\U0001d16f']), ('\U0001d1c0',
- &['\U0001d1bc', '\U0001d16f']), ('\U0002f800', &['\u4e3d']), ('\U0002f801', &['\u4e38']),
- ('\U0002f802', &['\u4e41']), ('\U0002f803', &['\U00020122']), ('\U0002f804', &['\u4f60']),
- ('\U0002f805', &['\u4fae']), ('\U0002f806', &['\u4fbb']), ('\U0002f807', &['\u5002']),
- ('\U0002f808', &['\u507a']), ('\U0002f809', &['\u5099']), ('\U0002f80a', &['\u50e7']),
- ('\U0002f80b', &['\u50cf']), ('\U0002f80c', &['\u349e']), ('\U0002f80d', &['\U0002063a']),
- ('\U0002f80e', &['\u514d']), ('\U0002f80f', &['\u5154']), ('\U0002f810', &['\u5164']),
- ('\U0002f811', &['\u5177']), ('\U0002f812', &['\U0002051c']), ('\U0002f813', &['\u34b9']),
- ('\U0002f814', &['\u5167']), ('\U0002f815', &['\u518d']), ('\U0002f816', &['\U0002054b']),
- ('\U0002f817', &['\u5197']), ('\U0002f818', &['\u51a4']), ('\U0002f819', &['\u4ecc']),
- ('\U0002f81a', &['\u51ac']), ('\U0002f81b', &['\u51b5']), ('\U0002f81c', &['\U000291df']),
- ('\U0002f81d', &['\u51f5']), ('\U0002f81e', &['\u5203']), ('\U0002f81f', &['\u34df']),
- ('\U0002f820', &['\u523b']), ('\U0002f821', &['\u5246']), ('\U0002f822', &['\u5272']),
- ('\U0002f823', &['\u5277']), ('\U0002f824', &['\u3515']), ('\U0002f825', &['\u52c7']),
- ('\U0002f826', &['\u52c9']), ('\U0002f827', &['\u52e4']), ('\U0002f828', &['\u52fa']),
- ('\U0002f829', &['\u5305']), ('\U0002f82a', &['\u5306']), ('\U0002f82b', &['\u5317']),
- ('\U0002f82c', &['\u5349']), ('\U0002f82d', &['\u5351']), ('\U0002f82e', &['\u535a']),
- ('\U0002f82f', &['\u5373']), ('\U0002f830', &['\u537d']), ('\U0002f831', &['\u537f']),
- ('\U0002f832', &['\u537f']), ('\U0002f833', &['\u537f']), ('\U0002f834', &['\U00020a2c']),
- ('\U0002f835', &['\u7070']), ('\U0002f836', &['\u53ca']), ('\U0002f837', &['\u53df']),
- ('\U0002f838', &['\U00020b63']), ('\U0002f839', &['\u53eb']), ('\U0002f83a', &['\u53f1']),
- ('\U0002f83b', &['\u5406']), ('\U0002f83c', &['\u549e']), ('\U0002f83d', &['\u5438']),
- ('\U0002f83e', &['\u5448']), ('\U0002f83f', &['\u5468']), ('\U0002f840', &['\u54a2']),
- ('\U0002f841', &['\u54f6']), ('\U0002f842', &['\u5510']), ('\U0002f843', &['\u5553']),
- ('\U0002f844', &['\u5563']), ('\U0002f845', &['\u5584']), ('\U0002f846', &['\u5584']),
- ('\U0002f847', &['\u5599']), ('\U0002f848', &['\u55ab']), ('\U0002f849', &['\u55b3']),
- ('\U0002f84a', &['\u55c2']), ('\U0002f84b', &['\u5716']), ('\U0002f84c', &['\u5606']),
- ('\U0002f84d', &['\u5717']), ('\U0002f84e', &['\u5651']), ('\U0002f84f', &['\u5674']),
- ('\U0002f850', &['\u5207']), ('\U0002f851', &['\u58ee']), ('\U0002f852', &['\u57ce']),
- ('\U0002f853', &['\u57f4']), ('\U0002f854', &['\u580d']), ('\U0002f855', &['\u578b']),
- ('\U0002f856', &['\u5832']), ('\U0002f857', &['\u5831']), ('\U0002f858', &['\u58ac']),
- ('\U0002f859', &['\U000214e4']), ('\U0002f85a', &['\u58f2']), ('\U0002f85b', &['\u58f7']),
- ('\U0002f85c', &['\u5906']), ('\U0002f85d', &['\u591a']), ('\U0002f85e', &['\u5922']),
- ('\U0002f85f', &['\u5962']), ('\U0002f860', &['\U000216a8']), ('\U0002f861',
- &['\U000216ea']), ('\U0002f862', &['\u59ec']), ('\U0002f863', &['\u5a1b']), ('\U0002f864',
- &['\u5a27']), ('\U0002f865', &['\u59d8']), ('\U0002f866', &['\u5a66']), ('\U0002f867',
- &['\u36ee']), ('\U0002f868', &['\u36fc']), ('\U0002f869', &['\u5b08']), ('\U0002f86a',
- &['\u5b3e']), ('\U0002f86b', &['\u5b3e']), ('\U0002f86c', &['\U000219c8']), ('\U0002f86d',
- &['\u5bc3']), ('\U0002f86e', &['\u5bd8']), ('\U0002f86f', &['\u5be7']), ('\U0002f870',
- &['\u5bf3']), ('\U0002f871', &['\U00021b18']), ('\U0002f872', &['\u5bff']), ('\U0002f873',
- &['\u5c06']), ('\U0002f874', &['\u5f53']), ('\U0002f875', &['\u5c22']), ('\U0002f876',
- &['\u3781']), ('\U0002f877', &['\u5c60']), ('\U0002f878', &['\u5c6e']), ('\U0002f879',
- &['\u5cc0']), ('\U0002f87a', &['\u5c8d']), ('\U0002f87b', &['\U00021de4']), ('\U0002f87c',
- &['\u5d43']), ('\U0002f87d', &['\U00021de6']), ('\U0002f87e', &['\u5d6e']), ('\U0002f87f',
- &['\u5d6b']), ('\U0002f880', &['\u5d7c']), ('\U0002f881', &['\u5de1']), ('\U0002f882',
- &['\u5de2']), ('\U0002f883', &['\u382f']), ('\U0002f884', &['\u5dfd']), ('\U0002f885',
- &['\u5e28']), ('\U0002f886', &['\u5e3d']), ('\U0002f887', &['\u5e69']), ('\U0002f888',
- &['\u3862']), ('\U0002f889', &['\U00022183']), ('\U0002f88a', &['\u387c']), ('\U0002f88b',
- &['\u5eb0']), ('\U0002f88c', &['\u5eb3']), ('\U0002f88d', &['\u5eb6']), ('\U0002f88e',
- &['\u5eca']), ('\U0002f88f', &['\U0002a392']), ('\U0002f890', &['\u5efe']), ('\U0002f891',
- &['\U00022331']), ('\U0002f892', &['\U00022331']), ('\U0002f893', &['\u8201']),
- ('\U0002f894', &['\u5f22']), ('\U0002f895', &['\u5f22']), ('\U0002f896', &['\u38c7']),
- ('\U0002f897', &['\U000232b8']), ('\U0002f898', &['\U000261da']), ('\U0002f899',
- &['\u5f62']), ('\U0002f89a', &['\u5f6b']), ('\U0002f89b', &['\u38e3']), ('\U0002f89c',
- &['\u5f9a']), ('\U0002f89d', &['\u5fcd']), ('\U0002f89e', &['\u5fd7']), ('\U0002f89f',
- &['\u5ff9']), ('\U0002f8a0', &['\u6081']), ('\U0002f8a1', &['\u393a']), ('\U0002f8a2',
- &['\u391c']), ('\U0002f8a3', &['\u6094']), ('\U0002f8a4', &['\U000226d4']), ('\U0002f8a5',
- &['\u60c7']), ('\U0002f8a6', &['\u6148']), ('\U0002f8a7', &['\u614c']), ('\U0002f8a8',
- &['\u614e']), ('\U0002f8a9', &['\u614c']), ('\U0002f8aa', &['\u617a']), ('\U0002f8ab',
- &['\u618e']), ('\U0002f8ac', &['\u61b2']), ('\U0002f8ad', &['\u61a4']), ('\U0002f8ae',
- &['\u61af']), ('\U0002f8af', &['\u61de']), ('\U0002f8b0', &['\u61f2']), ('\U0002f8b1',
- &['\u61f6']), ('\U0002f8b2', &['\u6210']), ('\U0002f8b3', &['\u621b']), ('\U0002f8b4',
- &['\u625d']), ('\U0002f8b5', &['\u62b1']), ('\U0002f8b6', &['\u62d4']), ('\U0002f8b7',
- &['\u6350']), ('\U0002f8b8', &['\U00022b0c']), ('\U0002f8b9', &['\u633d']), ('\U0002f8ba',
- &['\u62fc']), ('\U0002f8bb', &['\u6368']), ('\U0002f8bc', &['\u6383']), ('\U0002f8bd',
- &['\u63e4']), ('\U0002f8be', &['\U00022bf1']), ('\U0002f8bf', &['\u6422']), ('\U0002f8c0',
- &['\u63c5']), ('\U0002f8c1', &['\u63a9']), ('\U0002f8c2', &['\u3a2e']), ('\U0002f8c3',
- &['\u6469']), ('\U0002f8c4', &['\u647e']), ('\U0002f8c5', &['\u649d']), ('\U0002f8c6',
- &['\u6477']), ('\U0002f8c7', &['\u3a6c']), ('\U0002f8c8', &['\u654f']), ('\U0002f8c9',
- &['\u656c']), ('\U0002f8ca', &['\U0002300a']), ('\U0002f8cb', &['\u65e3']), ('\U0002f8cc',
- &['\u66f8']), ('\U0002f8cd', &['\u6649']), ('\U0002f8ce', &['\u3b19']), ('\U0002f8cf',
- &['\u6691']), ('\U0002f8d0', &['\u3b08']), ('\U0002f8d1', &['\u3ae4']), ('\U0002f8d2',
- &['\u5192']), ('\U0002f8d3', &['\u5195']), ('\U0002f8d4', &['\u6700']), ('\U0002f8d5',
- &['\u669c']), ('\U0002f8d6', &['\u80ad']), ('\U0002f8d7', &['\u43d9']), ('\U0002f8d8',
- &['\u6717']), ('\U0002f8d9', &['\u671b']), ('\U0002f8da', &['\u6721']), ('\U0002f8db',
- &['\u675e']), ('\U0002f8dc', &['\u6753']), ('\U0002f8dd', &['\U000233c3']), ('\U0002f8de',
- &['\u3b49']), ('\U0002f8df', &['\u67fa']), ('\U0002f8e0', &['\u6785']), ('\U0002f8e1',
- &['\u6852']), ('\U0002f8e2', &['\u6885']), ('\U0002f8e3', &['\U0002346d']), ('\U0002f8e4',
- &['\u688e']), ('\U0002f8e5', &['\u681f']), ('\U0002f8e6', &['\u6914']), ('\U0002f8e7',
- &['\u3b9d']), ('\U0002f8e8', &['\u6942']), ('\U0002f8e9', &['\u69a3']), ('\U0002f8ea',
- &['\u69ea']), ('\U0002f8eb', &['\u6aa8']), ('\U0002f8ec', &['\U000236a3']), ('\U0002f8ed',
- &['\u6adb']), ('\U0002f8ee', &['\u3c18']), ('\U0002f8ef', &['\u6b21']), ('\U0002f8f0',
- &['\U000238a7']), ('\U0002f8f1', &['\u6b54']), ('\U0002f8f2', &['\u3c4e']), ('\U0002f8f3',
- &['\u6b72']), ('\U0002f8f4', &['\u6b9f']), ('\U0002f8f5', &['\u6bba']), ('\U0002f8f6',
- &['\u6bbb']), ('\U0002f8f7', &['\U00023a8d']), ('\U0002f8f8', &['\U00021d0b']),
- ('\U0002f8f9', &['\U00023afa']), ('\U0002f8fa', &['\u6c4e']), ('\U0002f8fb',
- &['\U00023cbc']), ('\U0002f8fc', &['\u6cbf']), ('\U0002f8fd', &['\u6ccd']), ('\U0002f8fe',
- &['\u6c67']), ('\U0002f8ff', &['\u6d16']), ('\U0002f900', &['\u6d3e']), ('\U0002f901',
- &['\u6d77']), ('\U0002f902', &['\u6d41']), ('\U0002f903', &['\u6d69']), ('\U0002f904',
- &['\u6d78']), ('\U0002f905', &['\u6d85']), ('\U0002f906', &['\U00023d1e']), ('\U0002f907',
- &['\u6d34']), ('\U0002f908', &['\u6e2f']), ('\U0002f909', &['\u6e6e']), ('\U0002f90a',
- &['\u3d33']), ('\U0002f90b', &['\u6ecb']), ('\U0002f90c', &['\u6ec7']), ('\U0002f90d',
- &['\U00023ed1']), ('\U0002f90e', &['\u6df9']), ('\U0002f90f', &['\u6f6e']), ('\U0002f910',
- &['\U00023f5e']), ('\U0002f911', &['\U00023f8e']), ('\U0002f912', &['\u6fc6']),
- ('\U0002f913', &['\u7039']), ('\U0002f914', &['\u701e']), ('\U0002f915', &['\u701b']),
- ('\U0002f916', &['\u3d96']), ('\U0002f917', &['\u704a']), ('\U0002f918', &['\u707d']),
- ('\U0002f919', &['\u7077']), ('\U0002f91a', &['\u70ad']), ('\U0002f91b', &['\U00020525']),
- ('\U0002f91c', &['\u7145']), ('\U0002f91d', &['\U00024263']), ('\U0002f91e', &['\u719c']),
- ('\U0002f91f', &['\U000243ab']), ('\U0002f920', &['\u7228']), ('\U0002f921', &['\u7235']),
- ('\U0002f922', &['\u7250']), ('\U0002f923', &['\U00024608']), ('\U0002f924', &['\u7280']),
- ('\U0002f925', &['\u7295']), ('\U0002f926', &['\U00024735']), ('\U0002f927',
- &['\U00024814']), ('\U0002f928', &['\u737a']), ('\U0002f929', &['\u738b']), ('\U0002f92a',
- &['\u3eac']), ('\U0002f92b', &['\u73a5']), ('\U0002f92c', &['\u3eb8']), ('\U0002f92d',
- &['\u3eb8']), ('\U0002f92e', &['\u7447']), ('\U0002f92f', &['\u745c']), ('\U0002f930',
- &['\u7471']), ('\U0002f931', &['\u7485']), ('\U0002f932', &['\u74ca']), ('\U0002f933',
- &['\u3f1b']), ('\U0002f934', &['\u7524']), ('\U0002f935', &['\U00024c36']), ('\U0002f936',
- &['\u753e']), ('\U0002f937', &['\U00024c92']), ('\U0002f938', &['\u7570']), ('\U0002f939',
- &['\U0002219f']), ('\U0002f93a', &['\u7610']), ('\U0002f93b', &['\U00024fa1']),
- ('\U0002f93c', &['\U00024fb8']), ('\U0002f93d', &['\U00025044']), ('\U0002f93e',
- &['\u3ffc']), ('\U0002f93f', &['\u4008']), ('\U0002f940', &['\u76f4']), ('\U0002f941',
- &['\U000250f3']), ('\U0002f942', &['\U000250f2']), ('\U0002f943', &['\U00025119']),
- ('\U0002f944', &['\U00025133']), ('\U0002f945', &['\u771e']), ('\U0002f946', &['\u771f']),
- ('\U0002f947', &['\u771f']), ('\U0002f948', &['\u774a']), ('\U0002f949', &['\u4039']),
- ('\U0002f94a', &['\u778b']), ('\U0002f94b', &['\u4046']), ('\U0002f94c', &['\u4096']),
- ('\U0002f94d', &['\U0002541d']), ('\U0002f94e', &['\u784e']), ('\U0002f94f', &['\u788c']),
- ('\U0002f950', &['\u78cc']), ('\U0002f951', &['\u40e3']), ('\U0002f952', &['\U00025626']),
- ('\U0002f953', &['\u7956']), ('\U0002f954', &['\U0002569a']), ('\U0002f955',
- &['\U000256c5']), ('\U0002f956', &['\u798f']), ('\U0002f957', &['\u79eb']), ('\U0002f958',
- &['\u412f']), ('\U0002f959', &['\u7a40']), ('\U0002f95a', &['\u7a4a']), ('\U0002f95b',
- &['\u7a4f']), ('\U0002f95c', &['\U0002597c']), ('\U0002f95d', &['\U00025aa7']),
- ('\U0002f95e', &['\U00025aa7']), ('\U0002f95f', &['\u7aee']), ('\U0002f960', &['\u4202']),
- ('\U0002f961', &['\U00025bab']), ('\U0002f962', &['\u7bc6']), ('\U0002f963', &['\u7bc9']),
- ('\U0002f964', &['\u4227']), ('\U0002f965', &['\U00025c80']), ('\U0002f966', &['\u7cd2']),
- ('\U0002f967', &['\u42a0']), ('\U0002f968', &['\u7ce8']), ('\U0002f969', &['\u7ce3']),
- ('\U0002f96a', &['\u7d00']), ('\U0002f96b', &['\U00025f86']), ('\U0002f96c', &['\u7d63']),
- ('\U0002f96d', &['\u4301']), ('\U0002f96e', &['\u7dc7']), ('\U0002f96f', &['\u7e02']),
- ('\U0002f970', &['\u7e45']), ('\U0002f971', &['\u4334']), ('\U0002f972', &['\U00026228']),
- ('\U0002f973', &['\U00026247']), ('\U0002f974', &['\u4359']), ('\U0002f975',
- &['\U000262d9']), ('\U0002f976', &['\u7f7a']), ('\U0002f977', &['\U0002633e']),
- ('\U0002f978', &['\u7f95']), ('\U0002f979', &['\u7ffa']), ('\U0002f97a', &['\u8005']),
- ('\U0002f97b', &['\U000264da']), ('\U0002f97c', &['\U00026523']), ('\U0002f97d',
- &['\u8060']), ('\U0002f97e', &['\U000265a8']), ('\U0002f97f', &['\u8070']), ('\U0002f980',
- &['\U0002335f']), ('\U0002f981', &['\u43d5']), ('\U0002f982', &['\u80b2']), ('\U0002f983',
- &['\u8103']), ('\U0002f984', &['\u440b']), ('\U0002f985', &['\u813e']), ('\U0002f986',
- &['\u5ab5']), ('\U0002f987', &['\U000267a7']), ('\U0002f988', &['\U000267b5']),
- ('\U0002f989', &['\U00023393']), ('\U0002f98a', &['\U0002339c']), ('\U0002f98b',
- &['\u8201']), ('\U0002f98c', &['\u8204']), ('\U0002f98d', &['\u8f9e']), ('\U0002f98e',
- &['\u446b']), ('\U0002f98f', &['\u8291']), ('\U0002f990', &['\u828b']), ('\U0002f991',
- &['\u829d']), ('\U0002f992', &['\u52b3']), ('\U0002f993', &['\u82b1']), ('\U0002f994',
- &['\u82b3']), ('\U0002f995', &['\u82bd']), ('\U0002f996', &['\u82e6']), ('\U0002f997',
- &['\U00026b3c']), ('\U0002f998', &['\u82e5']), ('\U0002f999', &['\u831d']), ('\U0002f99a',
- &['\u8363']), ('\U0002f99b', &['\u83ad']), ('\U0002f99c', &['\u8323']), ('\U0002f99d',
- &['\u83bd']), ('\U0002f99e', &['\u83e7']), ('\U0002f99f', &['\u8457']), ('\U0002f9a0',
- &['\u8353']), ('\U0002f9a1', &['\u83ca']), ('\U0002f9a2', &['\u83cc']), ('\U0002f9a3',
- &['\u83dc']), ('\U0002f9a4', &['\U00026c36']), ('\U0002f9a5', &['\U00026d6b']),
- ('\U0002f9a6', &['\U00026cd5']), ('\U0002f9a7', &['\u452b']), ('\U0002f9a8', &['\u84f1']),
- ('\U0002f9a9', &['\u84f3']), ('\U0002f9aa', &['\u8516']), ('\U0002f9ab', &['\U000273ca']),
- ('\U0002f9ac', &['\u8564']), ('\U0002f9ad', &['\U00026f2c']), ('\U0002f9ae', &['\u455d']),
- ('\U0002f9af', &['\u4561']), ('\U0002f9b0', &['\U00026fb1']), ('\U0002f9b1',
- &['\U000270d2']), ('\U0002f9b2', &['\u456b']), ('\U0002f9b3', &['\u8650']), ('\U0002f9b4',
- &['\u865c']), ('\U0002f9b5', &['\u8667']), ('\U0002f9b6', &['\u8669']), ('\U0002f9b7',
- &['\u86a9']), ('\U0002f9b8', &['\u8688']), ('\U0002f9b9', &['\u870e']), ('\U0002f9ba',
- &['\u86e2']), ('\U0002f9bb', &['\u8779']), ('\U0002f9bc', &['\u8728']), ('\U0002f9bd',
- &['\u876b']), ('\U0002f9be', &['\u8786']), ('\U0002f9bf', &['\u45d7']), ('\U0002f9c0',
- &['\u87e1']), ('\U0002f9c1', &['\u8801']), ('\U0002f9c2', &['\u45f9']), ('\U0002f9c3',
- &['\u8860']), ('\U0002f9c4', &['\u8863']), ('\U0002f9c5', &['\U00027667']), ('\U0002f9c6',
- &['\u88d7']), ('\U0002f9c7', &['\u88de']), ('\U0002f9c8', &['\u4635']), ('\U0002f9c9',
- &['\u88fa']), ('\U0002f9ca', &['\u34bb']), ('\U0002f9cb', &['\U000278ae']), ('\U0002f9cc',
- &['\U00027966']), ('\U0002f9cd', &['\u46be']), ('\U0002f9ce', &['\u46c7']), ('\U0002f9cf',
- &['\u8aa0']), ('\U0002f9d0', &['\u8aed']), ('\U0002f9d1', &['\u8b8a']), ('\U0002f9d2',
- &['\u8c55']), ('\U0002f9d3', &['\U00027ca8']), ('\U0002f9d4', &['\u8cab']), ('\U0002f9d5',
- &['\u8cc1']), ('\U0002f9d6', &['\u8d1b']), ('\U0002f9d7', &['\u8d77']), ('\U0002f9d8',
- &['\U00027f2f']), ('\U0002f9d9', &['\U00020804']), ('\U0002f9da', &['\u8dcb']),
- ('\U0002f9db', &['\u8dbc']), ('\U0002f9dc', &['\u8df0']), ('\U0002f9dd', &['\U000208de']),
- ('\U0002f9de', &['\u8ed4']), ('\U0002f9df', &['\u8f38']), ('\U0002f9e0', &['\U000285d2']),
- ('\U0002f9e1', &['\U000285ed']), ('\U0002f9e2', &['\u9094']), ('\U0002f9e3', &['\u90f1']),
- ('\U0002f9e4', &['\u9111']), ('\U0002f9e5', &['\U0002872e']), ('\U0002f9e6', &['\u911b']),
- ('\U0002f9e7', &['\u9238']), ('\U0002f9e8', &['\u92d7']), ('\U0002f9e9', &['\u92d8']),
- ('\U0002f9ea', &['\u927c']), ('\U0002f9eb', &['\u93f9']), ('\U0002f9ec', &['\u9415']),
- ('\U0002f9ed', &['\U00028bfa']), ('\U0002f9ee', &['\u958b']), ('\U0002f9ef', &['\u4995']),
- ('\U0002f9f0', &['\u95b7']), ('\U0002f9f1', &['\U00028d77']), ('\U0002f9f2', &['\u49e6']),
- ('\U0002f9f3', &['\u96c3']), ('\U0002f9f4', &['\u5db2']), ('\U0002f9f5', &['\u9723']),
- ('\U0002f9f6', &['\U00029145']), ('\U0002f9f7', &['\U0002921a']), ('\U0002f9f8',
- &['\u4a6e']), ('\U0002f9f9', &['\u4a76']), ('\U0002f9fa', &['\u97e0']), ('\U0002f9fb',
- &['\U0002940a']), ('\U0002f9fc', &['\u4ab2']), ('\U0002f9fd', &['\U00029496']),
- ('\U0002f9fe', &['\u980b']), ('\U0002f9ff', &['\u980b']), ('\U0002fa00', &['\u9829']),
- ('\U0002fa01', &['\U000295b6']), ('\U0002fa02', &['\u98e2']), ('\U0002fa03', &['\u4b33']),
- ('\U0002fa04', &['\u9929']), ('\U0002fa05', &['\u99a7']), ('\U0002fa06', &['\u99c2']),
- ('\U0002fa07', &['\u99fe']), ('\U0002fa08', &['\u4bce']), ('\U0002fa09', &['\U00029b30']),
- ('\U0002fa0a', &['\u9b12']), ('\U0002fa0b', &['\u9c40']), ('\U0002fa0c', &['\u9cfd']),
- ('\U0002fa0d', &['\u4cce']), ('\U0002fa0e', &['\u4ced']), ('\U0002fa0f', &['\u9d67']),
- ('\U0002fa10', &['\U0002a0ce']), ('\U0002fa11', &['\u4cf8']), ('\U0002fa12',
- &['\U0002a105']), ('\U0002fa13', &['\U0002a20e']), ('\U0002fa14', &['\U0002a291']),
- ('\U0002fa15', &['\u9ebb']), ('\U0002fa16', &['\u4d56']), ('\U0002fa17', &['\u9ef9']),
- ('\U0002fa18', &['\u9efe']), ('\U0002fa19', &['\u9f05']), ('\U0002fa1a', &['\u9f0f']),
- ('\U0002fa1b', &['\u9f16']), ('\U0002fa1c', &['\u9f3b']), ('\U0002fa1d', &['\U0002a600'])
- ];
-
- // Compatibility decompositions
- static compatibility_table : &'static [(char, &'static [char])] = &[
- ('\xa0', &['\x20']), ('\xa8', &['\x20', '\u0308']), ('\xaa', &['\x61']), ('\xaf', &['\x20',
- '\u0304']), ('\xb2', &['\x32']), ('\xb3', &['\x33']), ('\xb4', &['\x20', '\u0301']),
- ('\xb5', &['\u03bc']), ('\xb8', &['\x20', '\u0327']), ('\xb9', &['\x31']), ('\xba',
- &['\x6f']), ('\xbc', &['\x31', '\u2044', '\x34']), ('\xbd', &['\x31', '\u2044', '\x32']),
- ('\xbe', &['\x33', '\u2044', '\x34']), ('\u0132', &['\x49', '\x4a']), ('\u0133', &['\x69',
- '\x6a']), ('\u013f', &['\x4c', '\xb7']), ('\u0140', &['\x6c', '\xb7']), ('\u0149',
- &['\u02bc', '\x6e']), ('\u017f', &['\x73']), ('\u01c4', &['\x44', '\u017d']), ('\u01c5',
- &['\x44', '\u017e']), ('\u01c6', &['\x64', '\u017e']), ('\u01c7', &['\x4c', '\x4a']),
- ('\u01c8', &['\x4c', '\x6a']), ('\u01c9', &['\x6c', '\x6a']), ('\u01ca', &['\x4e', '\x4a']),
- ('\u01cb', &['\x4e', '\x6a']), ('\u01cc', &['\x6e', '\x6a']), ('\u01f1', &['\x44', '\x5a']),
- ('\u01f2', &['\x44', '\x7a']), ('\u01f3', &['\x64', '\x7a']), ('\u02b0', &['\x68']),
- ('\u02b1', &['\u0266']), ('\u02b2', &['\x6a']), ('\u02b3', &['\x72']), ('\u02b4',
- &['\u0279']), ('\u02b5', &['\u027b']), ('\u02b6', &['\u0281']), ('\u02b7', &['\x77']),
- ('\u02b8', &['\x79']), ('\u02d8', &['\x20', '\u0306']), ('\u02d9', &['\x20', '\u0307']),
- ('\u02da', &['\x20', '\u030a']), ('\u02db', &['\x20', '\u0328']), ('\u02dc', &['\x20',
- '\u0303']), ('\u02dd', &['\x20', '\u030b']), ('\u02e0', &['\u0263']), ('\u02e1', &['\x6c']),
- ('\u02e2', &['\x73']), ('\u02e3', &['\x78']), ('\u02e4', &['\u0295']), ('\u037a', &['\x20',
- '\u0345']), ('\u0384', &['\x20', '\u0301']), ('\u03d0', &['\u03b2']), ('\u03d1',
- &['\u03b8']), ('\u03d2', &['\u03a5']), ('\u03d5', &['\u03c6']), ('\u03d6', &['\u03c0']),
- ('\u03f0', &['\u03ba']), ('\u03f1', &['\u03c1']), ('\u03f2', &['\u03c2']), ('\u03f4',
- &['\u0398']), ('\u03f5', &['\u03b5']), ('\u03f9', &['\u03a3']), ('\u0587', &['\u0565',
- '\u0582']), ('\u0675', &['\u0627', '\u0674']), ('\u0676', &['\u0648', '\u0674']), ('\u0677',
- &['\u06c7', '\u0674']), ('\u0678', &['\u064a', '\u0674']), ('\u0e33', &['\u0e4d',
- '\u0e32']), ('\u0eb3', &['\u0ecd', '\u0eb2']), ('\u0edc', &['\u0eab', '\u0e99']), ('\u0edd',
- &['\u0eab', '\u0ea1']), ('\u0f0c', &['\u0f0b']), ('\u0f77', &['\u0fb2', '\u0f81']),
- ('\u0f79', &['\u0fb3', '\u0f81']), ('\u10fc', &['\u10dc']), ('\u1d2c', &['\x41']),
- ('\u1d2d', &['\xc6']), ('\u1d2e', &['\x42']), ('\u1d30', &['\x44']), ('\u1d31', &['\x45']),
- ('\u1d32', &['\u018e']), ('\u1d33', &['\x47']), ('\u1d34', &['\x48']), ('\u1d35',
- &['\x49']), ('\u1d36', &['\x4a']), ('\u1d37', &['\x4b']), ('\u1d38', &['\x4c']), ('\u1d39',
- &['\x4d']), ('\u1d3a', &['\x4e']), ('\u1d3c', &['\x4f']), ('\u1d3d', &['\u0222']),
- ('\u1d3e', &['\x50']), ('\u1d3f', &['\x52']), ('\u1d40', &['\x54']), ('\u1d41', &['\x55']),
- ('\u1d42', &['\x57']), ('\u1d43', &['\x61']), ('\u1d44', &['\u0250']), ('\u1d45',
- &['\u0251']), ('\u1d46', &['\u1d02']), ('\u1d47', &['\x62']), ('\u1d48', &['\x64']),
- ('\u1d49', &['\x65']), ('\u1d4a', &['\u0259']), ('\u1d4b', &['\u025b']), ('\u1d4c',
- &['\u025c']), ('\u1d4d', &['\x67']), ('\u1d4f', &['\x6b']), ('\u1d50', &['\x6d']),
- ('\u1d51', &['\u014b']), ('\u1d52', &['\x6f']), ('\u1d53', &['\u0254']), ('\u1d54',
- &['\u1d16']), ('\u1d55', &['\u1d17']), ('\u1d56', &['\x70']), ('\u1d57', &['\x74']),
- ('\u1d58', &['\x75']), ('\u1d59', &['\u1d1d']), ('\u1d5a', &['\u026f']), ('\u1d5b',
- &['\x76']), ('\u1d5c', &['\u1d25']), ('\u1d5d', &['\u03b2']), ('\u1d5e', &['\u03b3']),
- ('\u1d5f', &['\u03b4']), ('\u1d60', &['\u03c6']), ('\u1d61', &['\u03c7']), ('\u1d62',
- &['\x69']), ('\u1d63', &['\x72']), ('\u1d64', &['\x75']), ('\u1d65', &['\x76']), ('\u1d66',
- &['\u03b2']), ('\u1d67', &['\u03b3']), ('\u1d68', &['\u03c1']), ('\u1d69', &['\u03c6']),
- ('\u1d6a', &['\u03c7']), ('\u1d78', &['\u043d']), ('\u1d9b', &['\u0252']), ('\u1d9c',
- &['\x63']), ('\u1d9d', &['\u0255']), ('\u1d9e', &['\xf0']), ('\u1d9f', &['\u025c']),
- ('\u1da0', &['\x66']), ('\u1da1', &['\u025f']), ('\u1da2', &['\u0261']), ('\u1da3',
- &['\u0265']), ('\u1da4', &['\u0268']), ('\u1da5', &['\u0269']), ('\u1da6', &['\u026a']),
- ('\u1da7', &['\u1d7b']), ('\u1da8', &['\u029d']), ('\u1da9', &['\u026d']), ('\u1daa',
- &['\u1d85']), ('\u1dab', &['\u029f']), ('\u1dac', &['\u0271']), ('\u1dad', &['\u0270']),
- ('\u1dae', &['\u0272']), ('\u1daf', &['\u0273']), ('\u1db0', &['\u0274']), ('\u1db1',
- &['\u0275']), ('\u1db2', &['\u0278']), ('\u1db3', &['\u0282']), ('\u1db4', &['\u0283']),
- ('\u1db5', &['\u01ab']), ('\u1db6', &['\u0289']), ('\u1db7', &['\u028a']), ('\u1db8',
- &['\u1d1c']), ('\u1db9', &['\u028b']), ('\u1dba', &['\u028c']), ('\u1dbb', &['\x7a']),
- ('\u1dbc', &['\u0290']), ('\u1dbd', &['\u0291']), ('\u1dbe', &['\u0292']), ('\u1dbf',
- &['\u03b8']), ('\u1e9a', &['\x61', '\u02be']), ('\u1fbd', &['\x20', '\u0313']), ('\u1fbf',
- &['\x20', '\u0313']), ('\u1fc0', &['\x20', '\u0342']), ('\u1ffe', &['\x20', '\u0314']),
- ('\u2002', &['\x20']), ('\u2003', &['\x20']), ('\u2004', &['\x20']), ('\u2005', &['\x20']),
- ('\u2006', &['\x20']), ('\u2007', &['\x20']), ('\u2008', &['\x20']), ('\u2009', &['\x20']),
- ('\u200a', &['\x20']), ('\u2011', &['\u2010']), ('\u2017', &['\x20', '\u0333']), ('\u2024',
- &['\x2e']), ('\u2025', &['\x2e', '\x2e']), ('\u2026', &['\x2e', '\x2e', '\x2e']), ('\u202f',
- &['\x20']), ('\u2033', &['\u2032', '\u2032']), ('\u2034', &['\u2032', '\u2032', '\u2032']),
- ('\u2036', &['\u2035', '\u2035']), ('\u2037', &['\u2035', '\u2035', '\u2035']), ('\u203c',
- &['\x21', '\x21']), ('\u203e', &['\x20', '\u0305']), ('\u2047', &['\x3f', '\x3f']),
- ('\u2048', &['\x3f', '\x21']), ('\u2049', &['\x21', '\x3f']), ('\u2057', &['\u2032',
- '\u2032', '\u2032', '\u2032']), ('\u205f', &['\x20']), ('\u2070', &['\x30']), ('\u2071',
- &['\x69']), ('\u2074', &['\x34']), ('\u2075', &['\x35']), ('\u2076', &['\x36']), ('\u2077',
- &['\x37']), ('\u2078', &['\x38']), ('\u2079', &['\x39']), ('\u207a', &['\x2b']), ('\u207b',
- &['\u2212']), ('\u207c', &['\x3d']), ('\u207d', &['\x28']), ('\u207e', &['\x29']),
- ('\u207f', &['\x6e']), ('\u2080', &['\x30']), ('\u2081', &['\x31']), ('\u2082', &['\x32']),
- ('\u2083', &['\x33']), ('\u2084', &['\x34']), ('\u2085', &['\x35']), ('\u2086', &['\x36']),
- ('\u2087', &['\x37']), ('\u2088', &['\x38']), ('\u2089', &['\x39']), ('\u208a', &['\x2b']),
- ('\u208b', &['\u2212']), ('\u208c', &['\x3d']), ('\u208d', &['\x28']), ('\u208e',
- &['\x29']), ('\u2090', &['\x61']), ('\u2091', &['\x65']), ('\u2092', &['\x6f']), ('\u2093',
- &['\x78']), ('\u2094', &['\u0259']), ('\u2095', &['\x68']), ('\u2096', &['\x6b']),
- ('\u2097', &['\x6c']), ('\u2098', &['\x6d']), ('\u2099', &['\x6e']), ('\u209a', &['\x70']),
- ('\u209b', &['\x73']), ('\u209c', &['\x74']), ('\u20a8', &['\x52', '\x73']), ('\u2100',
- &['\x61', '\x2f', '\x63']), ('\u2101', &['\x61', '\x2f', '\x73']), ('\u2102', &['\x43']),
- ('\u2103', &['\xb0', '\x43']), ('\u2105', &['\x63', '\x2f', '\x6f']), ('\u2106', &['\x63',
- '\x2f', '\x75']), ('\u2107', &['\u0190']), ('\u2109', &['\xb0', '\x46']), ('\u210a',
- &['\x67']), ('\u210b', &['\x48']), ('\u210c', &['\x48']), ('\u210d', &['\x48']), ('\u210e',
- &['\x68']), ('\u210f', &['\u0127']), ('\u2110', &['\x49']), ('\u2111', &['\x49']),
- ('\u2112', &['\x4c']), ('\u2113', &['\x6c']), ('\u2115', &['\x4e']), ('\u2116', &['\x4e',
- '\x6f']), ('\u2119', &['\x50']), ('\u211a', &['\x51']), ('\u211b', &['\x52']), ('\u211c',
- &['\x52']), ('\u211d', &['\x52']), ('\u2120', &['\x53', '\x4d']), ('\u2121', &['\x54',
- '\x45', '\x4c']), ('\u2122', &['\x54', '\x4d']), ('\u2124', &['\x5a']), ('\u2128',
- &['\x5a']), ('\u212c', &['\x42']), ('\u212d', &['\x43']), ('\u212f', &['\x65']), ('\u2130',
- &['\x45']), ('\u2131', &['\x46']), ('\u2133', &['\x4d']), ('\u2134', &['\x6f']), ('\u2135',
- &['\u05d0']), ('\u2136', &['\u05d1']), ('\u2137', &['\u05d2']), ('\u2138', &['\u05d3']),
- ('\u2139', &['\x69']), ('\u213b', &['\x46', '\x41', '\x58']), ('\u213c', &['\u03c0']),
- ('\u213d', &['\u03b3']), ('\u213e', &['\u0393']), ('\u213f', &['\u03a0']), ('\u2140',
- &['\u2211']), ('\u2145', &['\x44']), ('\u2146', &['\x64']), ('\u2147', &['\x65']),
- ('\u2148', &['\x69']), ('\u2149', &['\x6a']), ('\u2150', &['\x31', '\u2044', '\x37']),
- ('\u2151', &['\x31', '\u2044', '\x39']), ('\u2152', &['\x31', '\u2044', '\x31', '\x30']),
- ('\u2153', &['\x31', '\u2044', '\x33']), ('\u2154', &['\x32', '\u2044', '\x33']), ('\u2155',
- &['\x31', '\u2044', '\x35']), ('\u2156', &['\x32', '\u2044', '\x35']), ('\u2157', &['\x33',
- '\u2044', '\x35']), ('\u2158', &['\x34', '\u2044', '\x35']), ('\u2159', &['\x31', '\u2044',
- '\x36']), ('\u215a', &['\x35', '\u2044', '\x36']), ('\u215b', &['\x31', '\u2044', '\x38']),
- ('\u215c', &['\x33', '\u2044', '\x38']), ('\u215d', &['\x35', '\u2044', '\x38']), ('\u215e',
- &['\x37', '\u2044', '\x38']), ('\u215f', &['\x31', '\u2044']), ('\u2160', &['\x49']),
- ('\u2161', &['\x49', '\x49']), ('\u2162', &['\x49', '\x49', '\x49']), ('\u2163', &['\x49',
- '\x56']), ('\u2164', &['\x56']), ('\u2165', &['\x56', '\x49']), ('\u2166', &['\x56', '\x49',
- '\x49']), ('\u2167', &['\x56', '\x49', '\x49', '\x49']), ('\u2168', &['\x49', '\x58']),
- ('\u2169', &['\x58']), ('\u216a', &['\x58', '\x49']), ('\u216b', &['\x58', '\x49', '\x49']),
- ('\u216c', &['\x4c']), ('\u216d', &['\x43']), ('\u216e', &['\x44']), ('\u216f', &['\x4d']),
- ('\u2170', &['\x69']), ('\u2171', &['\x69', '\x69']), ('\u2172', &['\x69', '\x69', '\x69']),
- ('\u2173', &['\x69', '\x76']), ('\u2174', &['\x76']), ('\u2175', &['\x76', '\x69']),
- ('\u2176', &['\x76', '\x69', '\x69']), ('\u2177', &['\x76', '\x69', '\x69', '\x69']),
- ('\u2178', &['\x69', '\x78']), ('\u2179', &['\x78']), ('\u217a', &['\x78', '\x69']),
- ('\u217b', &['\x78', '\x69', '\x69']), ('\u217c', &['\x6c']), ('\u217d', &['\x63']),
- ('\u217e', &['\x64']), ('\u217f', &['\x6d']), ('\u2189', &['\x30', '\u2044', '\x33']),
- ('\u222c', &['\u222b', '\u222b']), ('\u222d', &['\u222b', '\u222b', '\u222b']), ('\u222f',
- &['\u222e', '\u222e']), ('\u2230', &['\u222e', '\u222e', '\u222e']), ('\u2460', &['\x31']),
- ('\u2461', &['\x32']), ('\u2462', &['\x33']), ('\u2463', &['\x34']), ('\u2464', &['\x35']),
- ('\u2465', &['\x36']), ('\u2466', &['\x37']), ('\u2467', &['\x38']), ('\u2468', &['\x39']),
- ('\u2469', &['\x31', '\x30']), ('\u246a', &['\x31', '\x31']), ('\u246b', &['\x31', '\x32']),
- ('\u246c', &['\x31', '\x33']), ('\u246d', &['\x31', '\x34']), ('\u246e', &['\x31', '\x35']),
- ('\u246f', &['\x31', '\x36']), ('\u2470', &['\x31', '\x37']), ('\u2471', &['\x31', '\x38']),
- ('\u2472', &['\x31', '\x39']), ('\u2473', &['\x32', '\x30']), ('\u2474', &['\x28', '\x31',
- '\x29']), ('\u2475', &['\x28', '\x32', '\x29']), ('\u2476', &['\x28', '\x33', '\x29']),
- ('\u2477', &['\x28', '\x34', '\x29']), ('\u2478', &['\x28', '\x35', '\x29']), ('\u2479',
- &['\x28', '\x36', '\x29']), ('\u247a', &['\x28', '\x37', '\x29']), ('\u247b', &['\x28',
- '\x38', '\x29']), ('\u247c', &['\x28', '\x39', '\x29']), ('\u247d', &['\x28', '\x31',
- '\x30', '\x29']), ('\u247e', &['\x28', '\x31', '\x31', '\x29']), ('\u247f', &['\x28',
- '\x31', '\x32', '\x29']), ('\u2480', &['\x28', '\x31', '\x33', '\x29']), ('\u2481',
- &['\x28', '\x31', '\x34', '\x29']), ('\u2482', &['\x28', '\x31', '\x35', '\x29']),
- ('\u2483', &['\x28', '\x31', '\x36', '\x29']), ('\u2484', &['\x28', '\x31', '\x37',
- '\x29']), ('\u2485', &['\x28', '\x31', '\x38', '\x29']), ('\u2486', &['\x28', '\x31',
- '\x39', '\x29']), ('\u2487', &['\x28', '\x32', '\x30', '\x29']), ('\u2488', &['\x31',
- '\x2e']), ('\u2489', &['\x32', '\x2e']), ('\u248a', &['\x33', '\x2e']), ('\u248b', &['\x34',
- '\x2e']), ('\u248c', &['\x35', '\x2e']), ('\u248d', &['\x36', '\x2e']), ('\u248e', &['\x37',
- '\x2e']), ('\u248f', &['\x38', '\x2e']), ('\u2490', &['\x39', '\x2e']), ('\u2491', &['\x31',
- '\x30', '\x2e']), ('\u2492', &['\x31', '\x31', '\x2e']), ('\u2493', &['\x31', '\x32',
- '\x2e']), ('\u2494', &['\x31', '\x33', '\x2e']), ('\u2495', &['\x31', '\x34', '\x2e']),
- ('\u2496', &['\x31', '\x35', '\x2e']), ('\u2497', &['\x31', '\x36', '\x2e']), ('\u2498',
- &['\x31', '\x37', '\x2e']), ('\u2499', &['\x31', '\x38', '\x2e']), ('\u249a', &['\x31',
- '\x39', '\x2e']), ('\u249b', &['\x32', '\x30', '\x2e']), ('\u249c', &['\x28', '\x61',
- '\x29']), ('\u249d', &['\x28', '\x62', '\x29']), ('\u249e', &['\x28', '\x63', '\x29']),
- ('\u249f', &['\x28', '\x64', '\x29']), ('\u24a0', &['\x28', '\x65', '\x29']), ('\u24a1',
- &['\x28', '\x66', '\x29']), ('\u24a2', &['\x28', '\x67', '\x29']), ('\u24a3', &['\x28',
- '\x68', '\x29']), ('\u24a4', &['\x28', '\x69', '\x29']), ('\u24a5', &['\x28', '\x6a',
- '\x29']), ('\u24a6', &['\x28', '\x6b', '\x29']), ('\u24a7', &['\x28', '\x6c', '\x29']),
- ('\u24a8', &['\x28', '\x6d', '\x29']), ('\u24a9', &['\x28', '\x6e', '\x29']), ('\u24aa',
- &['\x28', '\x6f', '\x29']), ('\u24ab', &['\x28', '\x70', '\x29']), ('\u24ac', &['\x28',
- '\x71', '\x29']), ('\u24ad', &['\x28', '\x72', '\x29']), ('\u24ae', &['\x28', '\x73',
- '\x29']), ('\u24af', &['\x28', '\x74', '\x29']), ('\u24b0', &['\x28', '\x75', '\x29']),
- ('\u24b1', &['\x28', '\x76', '\x29']), ('\u24b2', &['\x28', '\x77', '\x29']), ('\u24b3',
- &['\x28', '\x78', '\x29']), ('\u24b4', &['\x28', '\x79', '\x29']), ('\u24b5', &['\x28',
- '\x7a', '\x29']), ('\u24b6', &['\x41']), ('\u24b7', &['\x42']), ('\u24b8', &['\x43']),
- ('\u24b9', &['\x44']), ('\u24ba', &['\x45']), ('\u24bb', &['\x46']), ('\u24bc', &['\x47']),
- ('\u24bd', &['\x48']), ('\u24be', &['\x49']), ('\u24bf', &['\x4a']), ('\u24c0', &['\x4b']),
- ('\u24c1', &['\x4c']), ('\u24c2', &['\x4d']), ('\u24c3', &['\x4e']), ('\u24c4', &['\x4f']),
- ('\u24c5', &['\x50']), ('\u24c6', &['\x51']), ('\u24c7', &['\x52']), ('\u24c8', &['\x53']),
- ('\u24c9', &['\x54']), ('\u24ca', &['\x55']), ('\u24cb', &['\x56']), ('\u24cc', &['\x57']),
- ('\u24cd', &['\x58']), ('\u24ce', &['\x59']), ('\u24cf', &['\x5a']), ('\u24d0', &['\x61']),
- ('\u24d1', &['\x62']), ('\u24d2', &['\x63']), ('\u24d3', &['\x64']), ('\u24d4', &['\x65']),
- ('\u24d5', &['\x66']), ('\u24d6', &['\x67']), ('\u24d7', &['\x68']), ('\u24d8', &['\x69']),
- ('\u24d9', &['\x6a']), ('\u24da', &['\x6b']), ('\u24db', &['\x6c']), ('\u24dc', &['\x6d']),
- ('\u24dd', &['\x6e']), ('\u24de', &['\x6f']), ('\u24df', &['\x70']), ('\u24e0', &['\x71']),
- ('\u24e1', &['\x72']), ('\u24e2', &['\x73']), ('\u24e3', &['\x74']), ('\u24e4', &['\x75']),
- ('\u24e5', &['\x76']), ('\u24e6', &['\x77']), ('\u24e7', &['\x78']), ('\u24e8', &['\x79']),
- ('\u24e9', &['\x7a']), ('\u24ea', &['\x30']), ('\u2a0c', &['\u222b', '\u222b', '\u222b',
- '\u222b']), ('\u2a74', &['\x3a', '\x3a', '\x3d']), ('\u2a75', &['\x3d', '\x3d']), ('\u2a76',
- &['\x3d', '\x3d', '\x3d']), ('\u2c7c', &['\x6a']), ('\u2c7d', &['\x56']), ('\u2d6f',
- &['\u2d61']), ('\u2e9f', &['\u6bcd']), ('\u2ef3', &['\u9f9f']), ('\u2f00', &['\u4e00']),
- ('\u2f01', &['\u4e28']), ('\u2f02', &['\u4e36']), ('\u2f03', &['\u4e3f']), ('\u2f04',
- &['\u4e59']), ('\u2f05', &['\u4e85']), ('\u2f06', &['\u4e8c']), ('\u2f07', &['\u4ea0']),
- ('\u2f08', &['\u4eba']), ('\u2f09', &['\u513f']), ('\u2f0a', &['\u5165']), ('\u2f0b',
- &['\u516b']), ('\u2f0c', &['\u5182']), ('\u2f0d', &['\u5196']), ('\u2f0e', &['\u51ab']),
- ('\u2f0f', &['\u51e0']), ('\u2f10', &['\u51f5']), ('\u2f11', &['\u5200']), ('\u2f12',
- &['\u529b']), ('\u2f13', &['\u52f9']), ('\u2f14', &['\u5315']), ('\u2f15', &['\u531a']),
- ('\u2f16', &['\u5338']), ('\u2f17', &['\u5341']), ('\u2f18', &['\u535c']), ('\u2f19',
- &['\u5369']), ('\u2f1a', &['\u5382']), ('\u2f1b', &['\u53b6']), ('\u2f1c', &['\u53c8']),
- ('\u2f1d', &['\u53e3']), ('\u2f1e', &['\u56d7']), ('\u2f1f', &['\u571f']), ('\u2f20',
- &['\u58eb']), ('\u2f21', &['\u5902']), ('\u2f22', &['\u590a']), ('\u2f23', &['\u5915']),
- ('\u2f24', &['\u5927']), ('\u2f25', &['\u5973']), ('\u2f26', &['\u5b50']), ('\u2f27',
- &['\u5b80']), ('\u2f28', &['\u5bf8']), ('\u2f29', &['\u5c0f']), ('\u2f2a', &['\u5c22']),
- ('\u2f2b', &['\u5c38']), ('\u2f2c', &['\u5c6e']), ('\u2f2d', &['\u5c71']), ('\u2f2e',
- &['\u5ddb']), ('\u2f2f', &['\u5de5']), ('\u2f30', &['\u5df1']), ('\u2f31', &['\u5dfe']),
- ('\u2f32', &['\u5e72']), ('\u2f33', &['\u5e7a']), ('\u2f34', &['\u5e7f']), ('\u2f35',
- &['\u5ef4']), ('\u2f36', &['\u5efe']), ('\u2f37', &['\u5f0b']), ('\u2f38', &['\u5f13']),
- ('\u2f39', &['\u5f50']), ('\u2f3a', &['\u5f61']), ('\u2f3b', &['\u5f73']), ('\u2f3c',
- &['\u5fc3']), ('\u2f3d', &['\u6208']), ('\u2f3e', &['\u6236']), ('\u2f3f', &['\u624b']),
- ('\u2f40', &['\u652f']), ('\u2f41', &['\u6534']), ('\u2f42', &['\u6587']), ('\u2f43',
- &['\u6597']), ('\u2f44', &['\u65a4']), ('\u2f45', &['\u65b9']), ('\u2f46', &['\u65e0']),
- ('\u2f47', &['\u65e5']), ('\u2f48', &['\u66f0']), ('\u2f49', &['\u6708']), ('\u2f4a',
- &['\u6728']), ('\u2f4b', &['\u6b20']), ('\u2f4c', &['\u6b62']), ('\u2f4d', &['\u6b79']),
- ('\u2f4e', &['\u6bb3']), ('\u2f4f', &['\u6bcb']), ('\u2f50', &['\u6bd4']), ('\u2f51',
- &['\u6bdb']), ('\u2f52', &['\u6c0f']), ('\u2f53', &['\u6c14']), ('\u2f54', &['\u6c34']),
- ('\u2f55', &['\u706b']), ('\u2f56', &['\u722a']), ('\u2f57', &['\u7236']), ('\u2f58',
- &['\u723b']), ('\u2f59', &['\u723f']), ('\u2f5a', &['\u7247']), ('\u2f5b', &['\u7259']),
- ('\u2f5c', &['\u725b']), ('\u2f5d', &['\u72ac']), ('\u2f5e', &['\u7384']), ('\u2f5f',
- &['\u7389']), ('\u2f60', &['\u74dc']), ('\u2f61', &['\u74e6']), ('\u2f62', &['\u7518']),
- ('\u2f63', &['\u751f']), ('\u2f64', &['\u7528']), ('\u2f65', &['\u7530']), ('\u2f66',
- &['\u758b']), ('\u2f67', &['\u7592']), ('\u2f68', &['\u7676']), ('\u2f69', &['\u767d']),
- ('\u2f6a', &['\u76ae']), ('\u2f6b', &['\u76bf']), ('\u2f6c', &['\u76ee']), ('\u2f6d',
- &['\u77db']), ('\u2f6e', &['\u77e2']), ('\u2f6f', &['\u77f3']), ('\u2f70', &['\u793a']),
- ('\u2f71', &['\u79b8']), ('\u2f72', &['\u79be']), ('\u2f73', &['\u7a74']), ('\u2f74',
- &['\u7acb']), ('\u2f75', &['\u7af9']), ('\u2f76', &['\u7c73']), ('\u2f77', &['\u7cf8']),
- ('\u2f78', &['\u7f36']), ('\u2f79', &['\u7f51']), ('\u2f7a', &['\u7f8a']), ('\u2f7b',
- &['\u7fbd']), ('\u2f7c', &['\u8001']), ('\u2f7d', &['\u800c']), ('\u2f7e', &['\u8012']),
- ('\u2f7f', &['\u8033']), ('\u2f80', &['\u807f']), ('\u2f81', &['\u8089']), ('\u2f82',
- &['\u81e3']), ('\u2f83', &['\u81ea']), ('\u2f84', &['\u81f3']), ('\u2f85', &['\u81fc']),
- ('\u2f86', &['\u820c']), ('\u2f87', &['\u821b']), ('\u2f88', &['\u821f']), ('\u2f89',
- &['\u826e']), ('\u2f8a', &['\u8272']), ('\u2f8b', &['\u8278']), ('\u2f8c', &['\u864d']),
- ('\u2f8d', &['\u866b']), ('\u2f8e', &['\u8840']), ('\u2f8f', &['\u884c']), ('\u2f90',
- &['\u8863']), ('\u2f91', &['\u897e']), ('\u2f92', &['\u898b']), ('\u2f93', &['\u89d2']),
- ('\u2f94', &['\u8a00']), ('\u2f95', &['\u8c37']), ('\u2f96', &['\u8c46']), ('\u2f97',
- &['\u8c55']), ('\u2f98', &['\u8c78']), ('\u2f99', &['\u8c9d']), ('\u2f9a', &['\u8d64']),
- ('\u2f9b', &['\u8d70']), ('\u2f9c', &['\u8db3']), ('\u2f9d', &['\u8eab']), ('\u2f9e',
- &['\u8eca']), ('\u2f9f', &['\u8f9b']), ('\u2fa0', &['\u8fb0']), ('\u2fa1', &['\u8fb5']),
- ('\u2fa2', &['\u9091']), ('\u2fa3', &['\u9149']), ('\u2fa4', &['\u91c6']), ('\u2fa5',
- &['\u91cc']), ('\u2fa6', &['\u91d1']), ('\u2fa7', &['\u9577']), ('\u2fa8', &['\u9580']),
- ('\u2fa9', &['\u961c']), ('\u2faa', &['\u96b6']), ('\u2fab', &['\u96b9']), ('\u2fac',
- &['\u96e8']), ('\u2fad', &['\u9751']), ('\u2fae', &['\u975e']), ('\u2faf', &['\u9762']),
- ('\u2fb0', &['\u9769']), ('\u2fb1', &['\u97cb']), ('\u2fb2', &['\u97ed']), ('\u2fb3',
- &['\u97f3']), ('\u2fb4', &['\u9801']), ('\u2fb5', &['\u98a8']), ('\u2fb6', &['\u98db']),
- ('\u2fb7', &['\u98df']), ('\u2fb8', &['\u9996']), ('\u2fb9', &['\u9999']), ('\u2fba',
- &['\u99ac']), ('\u2fbb', &['\u9aa8']), ('\u2fbc', &['\u9ad8']), ('\u2fbd', &['\u9adf']),
- ('\u2fbe', &['\u9b25']), ('\u2fbf', &['\u9b2f']), ('\u2fc0', &['\u9b32']), ('\u2fc1',
- &['\u9b3c']), ('\u2fc2', &['\u9b5a']), ('\u2fc3', &['\u9ce5']), ('\u2fc4', &['\u9e75']),
- ('\u2fc5', &['\u9e7f']), ('\u2fc6', &['\u9ea5']), ('\u2fc7', &['\u9ebb']), ('\u2fc8',
- &['\u9ec3']), ('\u2fc9', &['\u9ecd']), ('\u2fca', &['\u9ed1']), ('\u2fcb', &['\u9ef9']),
- ('\u2fcc', &['\u9efd']), ('\u2fcd', &['\u9f0e']), ('\u2fce', &['\u9f13']), ('\u2fcf',
- &['\u9f20']), ('\u2fd0', &['\u9f3b']), ('\u2fd1', &['\u9f4a']), ('\u2fd2', &['\u9f52']),
- ('\u2fd3', &['\u9f8d']), ('\u2fd4', &['\u9f9c']), ('\u2fd5', &['\u9fa0']), ('\u3000',
- &['\x20']), ('\u3036', &['\u3012']), ('\u3038', &['\u5341']), ('\u3039', &['\u5344']),
- ('\u303a', &['\u5345']), ('\u309b', &['\x20', '\u3099']), ('\u309c', &['\x20', '\u309a']),
- ('\u309f', &['\u3088', '\u308a']), ('\u30ff', &['\u30b3', '\u30c8']), ('\u3131',
- &['\u1100']), ('\u3132', &['\u1101']), ('\u3133', &['\u11aa']), ('\u3134', &['\u1102']),
- ('\u3135', &['\u11ac']), ('\u3136', &['\u11ad']), ('\u3137', &['\u1103']), ('\u3138',
- &['\u1104']), ('\u3139', &['\u1105']), ('\u313a', &['\u11b0']), ('\u313b', &['\u11b1']),
- ('\u313c', &['\u11b2']), ('\u313d', &['\u11b3']), ('\u313e', &['\u11b4']), ('\u313f',
- &['\u11b5']), ('\u3140', &['\u111a']), ('\u3141', &['\u1106']), ('\u3142', &['\u1107']),
- ('\u3143', &['\u1108']), ('\u3144', &['\u1121']), ('\u3145', &['\u1109']), ('\u3146',
- &['\u110a']), ('\u3147', &['\u110b']), ('\u3148', &['\u110c']), ('\u3149', &['\u110d']),
- ('\u314a', &['\u110e']), ('\u314b', &['\u110f']), ('\u314c', &['\u1110']), ('\u314d',
- &['\u1111']), ('\u314e', &['\u1112']), ('\u314f', &['\u1161']), ('\u3150', &['\u1162']),
- ('\u3151', &['\u1163']), ('\u3152', &['\u1164']), ('\u3153', &['\u1165']), ('\u3154',
- &['\u1166']), ('\u3155', &['\u1167']), ('\u3156', &['\u1168']), ('\u3157', &['\u1169']),
- ('\u3158', &['\u116a']), ('\u3159', &['\u116b']), ('\u315a', &['\u116c']), ('\u315b',
- &['\u116d']), ('\u315c', &['\u116e']), ('\u315d', &['\u116f']), ('\u315e', &['\u1170']),
- ('\u315f', &['\u1171']), ('\u3160', &['\u1172']), ('\u3161', &['\u1173']), ('\u3162',
- &['\u1174']), ('\u3163', &['\u1175']), ('\u3164', &['\u1160']), ('\u3165', &['\u1114']),
- ('\u3166', &['\u1115']), ('\u3167', &['\u11c7']), ('\u3168', &['\u11c8']), ('\u3169',
- &['\u11cc']), ('\u316a', &['\u11ce']), ('\u316b', &['\u11d3']), ('\u316c', &['\u11d7']),
- ('\u316d', &['\u11d9']), ('\u316e', &['\u111c']), ('\u316f', &['\u11dd']), ('\u3170',
- &['\u11df']), ('\u3171', &['\u111d']), ('\u3172', &['\u111e']), ('\u3173', &['\u1120']),
- ('\u3174', &['\u1122']), ('\u3175', &['\u1123']), ('\u3176', &['\u1127']), ('\u3177',
- &['\u1129']), ('\u3178', &['\u112b']), ('\u3179', &['\u112c']), ('\u317a', &['\u112d']),
- ('\u317b', &['\u112e']), ('\u317c', &['\u112f']), ('\u317d', &['\u1132']), ('\u317e',
- &['\u1136']), ('\u317f', &['\u1140']), ('\u3180', &['\u1147']), ('\u3181', &['\u114c']),
- ('\u3182', &['\u11f1']), ('\u3183', &['\u11f2']), ('\u3184', &['\u1157']), ('\u3185',
- &['\u1158']), ('\u3186', &['\u1159']), ('\u3187', &['\u1184']), ('\u3188', &['\u1185']),
- ('\u3189', &['\u1188']), ('\u318a', &['\u1191']), ('\u318b', &['\u1192']), ('\u318c',
- &['\u1194']), ('\u318d', &['\u119e']), ('\u318e', &['\u11a1']), ('\u3192', &['\u4e00']),
- ('\u3193', &['\u4e8c']), ('\u3194', &['\u4e09']), ('\u3195', &['\u56db']), ('\u3196',
- &['\u4e0a']), ('\u3197', &['\u4e2d']), ('\u3198', &['\u4e0b']), ('\u3199', &['\u7532']),
- ('\u319a', &['\u4e59']), ('\u319b', &['\u4e19']), ('\u319c', &['\u4e01']), ('\u319d',
- &['\u5929']), ('\u319e', &['\u5730']), ('\u319f', &['\u4eba']), ('\u3200', &['\x28',
- '\u1100', '\x29']), ('\u3201', &['\x28', '\u1102', '\x29']), ('\u3202', &['\x28', '\u1103',
- '\x29']), ('\u3203', &['\x28', '\u1105', '\x29']), ('\u3204', &['\x28', '\u1106', '\x29']),
- ('\u3205', &['\x28', '\u1107', '\x29']), ('\u3206', &['\x28', '\u1109', '\x29']), ('\u3207',
- &['\x28', '\u110b', '\x29']), ('\u3208', &['\x28', '\u110c', '\x29']), ('\u3209', &['\x28',
- '\u110e', '\x29']), ('\u320a', &['\x28', '\u110f', '\x29']), ('\u320b', &['\x28', '\u1110',
- '\x29']), ('\u320c', &['\x28', '\u1111', '\x29']), ('\u320d', &['\x28', '\u1112', '\x29']),
- ('\u320e', &['\x28', '\u1100', '\u1161', '\x29']), ('\u320f', &['\x28', '\u1102', '\u1161',
- '\x29']), ('\u3210', &['\x28', '\u1103', '\u1161', '\x29']), ('\u3211', &['\x28', '\u1105',
- '\u1161', '\x29']), ('\u3212', &['\x28', '\u1106', '\u1161', '\x29']), ('\u3213', &['\x28',
- '\u1107', '\u1161', '\x29']), ('\u3214', &['\x28', '\u1109', '\u1161', '\x29']), ('\u3215',
- &['\x28', '\u110b', '\u1161', '\x29']), ('\u3216', &['\x28', '\u110c', '\u1161', '\x29']),
- ('\u3217', &['\x28', '\u110e', '\u1161', '\x29']), ('\u3218', &['\x28', '\u110f', '\u1161',
- '\x29']), ('\u3219', &['\x28', '\u1110', '\u1161', '\x29']), ('\u321a', &['\x28', '\u1111',
- '\u1161', '\x29']), ('\u321b', &['\x28', '\u1112', '\u1161', '\x29']), ('\u321c', &['\x28',
- '\u110c', '\u116e', '\x29']), ('\u321d', &['\x28', '\u110b', '\u1169', '\u110c', '\u1165',
- '\u11ab', '\x29']), ('\u321e', &['\x28', '\u110b', '\u1169', '\u1112', '\u116e', '\x29']),
- ('\u3220', &['\x28', '\u4e00', '\x29']), ('\u3221', &['\x28', '\u4e8c', '\x29']), ('\u3222',
- &['\x28', '\u4e09', '\x29']), ('\u3223', &['\x28', '\u56db', '\x29']), ('\u3224', &['\x28',
- '\u4e94', '\x29']), ('\u3225', &['\x28', '\u516d', '\x29']), ('\u3226', &['\x28', '\u4e03',
- '\x29']), ('\u3227', &['\x28', '\u516b', '\x29']), ('\u3228', &['\x28', '\u4e5d', '\x29']),
- ('\u3229', &['\x28', '\u5341', '\x29']), ('\u322a', &['\x28', '\u6708', '\x29']), ('\u322b',
- &['\x28', '\u706b', '\x29']), ('\u322c', &['\x28', '\u6c34', '\x29']), ('\u322d', &['\x28',
- '\u6728', '\x29']), ('\u322e', &['\x28', '\u91d1', '\x29']), ('\u322f', &['\x28', '\u571f',
- '\x29']), ('\u3230', &['\x28', '\u65e5', '\x29']), ('\u3231', &['\x28', '\u682a', '\x29']),
- ('\u3232', &['\x28', '\u6709', '\x29']), ('\u3233', &['\x28', '\u793e', '\x29']), ('\u3234',
- &['\x28', '\u540d', '\x29']), ('\u3235', &['\x28', '\u7279', '\x29']), ('\u3236', &['\x28',
- '\u8ca1', '\x29']), ('\u3237', &['\x28', '\u795d', '\x29']), ('\u3238', &['\x28', '\u52b4',
- '\x29']), ('\u3239', &['\x28', '\u4ee3', '\x29']), ('\u323a', &['\x28', '\u547c', '\x29']),
- ('\u323b', &['\x28', '\u5b66', '\x29']), ('\u323c', &['\x28', '\u76e3', '\x29']), ('\u323d',
- &['\x28', '\u4f01', '\x29']), ('\u323e', &['\x28', '\u8cc7', '\x29']), ('\u323f', &['\x28',
- '\u5354', '\x29']), ('\u3240', &['\x28', '\u796d', '\x29']), ('\u3241', &['\x28', '\u4f11',
- '\x29']), ('\u3242', &['\x28', '\u81ea', '\x29']), ('\u3243', &['\x28', '\u81f3', '\x29']),
- ('\u3244', &['\u554f']), ('\u3245', &['\u5e7c']), ('\u3246', &['\u6587']), ('\u3247',
- &['\u7b8f']), ('\u3250', &['\x50', '\x54', '\x45']), ('\u3251', &['\x32', '\x31']),
- ('\u3252', &['\x32', '\x32']), ('\u3253', &['\x32', '\x33']), ('\u3254', &['\x32', '\x34']),
- ('\u3255', &['\x32', '\x35']), ('\u3256', &['\x32', '\x36']), ('\u3257', &['\x32', '\x37']),
- ('\u3258', &['\x32', '\x38']), ('\u3259', &['\x32', '\x39']), ('\u325a', &['\x33', '\x30']),
- ('\u325b', &['\x33', '\x31']), ('\u325c', &['\x33', '\x32']), ('\u325d', &['\x33', '\x33']),
- ('\u325e', &['\x33', '\x34']), ('\u325f', &['\x33', '\x35']), ('\u3260', &['\u1100']),
- ('\u3261', &['\u1102']), ('\u3262', &['\u1103']), ('\u3263', &['\u1105']), ('\u3264',
- &['\u1106']), ('\u3265', &['\u1107']), ('\u3266', &['\u1109']), ('\u3267', &['\u110b']),
- ('\u3268', &['\u110c']), ('\u3269', &['\u110e']), ('\u326a', &['\u110f']), ('\u326b',
- &['\u1110']), ('\u326c', &['\u1111']), ('\u326d', &['\u1112']), ('\u326e', &['\u1100',
- '\u1161']), ('\u326f', &['\u1102', '\u1161']), ('\u3270', &['\u1103', '\u1161']), ('\u3271',
- &['\u1105', '\u1161']), ('\u3272', &['\u1106', '\u1161']), ('\u3273', &['\u1107',
- '\u1161']), ('\u3274', &['\u1109', '\u1161']), ('\u3275', &['\u110b', '\u1161']), ('\u3276',
- &['\u110c', '\u1161']), ('\u3277', &['\u110e', '\u1161']), ('\u3278', &['\u110f',
- '\u1161']), ('\u3279', &['\u1110', '\u1161']), ('\u327a', &['\u1111', '\u1161']), ('\u327b',
- &['\u1112', '\u1161']), ('\u327c', &['\u110e', '\u1161', '\u11b7', '\u1100', '\u1169']),
- ('\u327d', &['\u110c', '\u116e', '\u110b', '\u1174']), ('\u327e', &['\u110b', '\u116e']),
- ('\u3280', &['\u4e00']), ('\u3281', &['\u4e8c']), ('\u3282', &['\u4e09']), ('\u3283',
- &['\u56db']), ('\u3284', &['\u4e94']), ('\u3285', &['\u516d']), ('\u3286', &['\u4e03']),
- ('\u3287', &['\u516b']), ('\u3288', &['\u4e5d']), ('\u3289', &['\u5341']), ('\u328a',
- &['\u6708']), ('\u328b', &['\u706b']), ('\u328c', &['\u6c34']), ('\u328d', &['\u6728']),
- ('\u328e', &['\u91d1']), ('\u328f', &['\u571f']), ('\u3290', &['\u65e5']), ('\u3291',
- &['\u682a']), ('\u3292', &['\u6709']), ('\u3293', &['\u793e']), ('\u3294', &['\u540d']),
- ('\u3295', &['\u7279']), ('\u3296', &['\u8ca1']), ('\u3297', &['\u795d']), ('\u3298',
- &['\u52b4']), ('\u3299', &['\u79d8']), ('\u329a', &['\u7537']), ('\u329b', &['\u5973']),
- ('\u329c', &['\u9069']), ('\u329d', &['\u512a']), ('\u329e', &['\u5370']), ('\u329f',
- &['\u6ce8']), ('\u32a0', &['\u9805']), ('\u32a1', &['\u4f11']), ('\u32a2', &['\u5199']),
- ('\u32a3', &['\u6b63']), ('\u32a4', &['\u4e0a']), ('\u32a5', &['\u4e2d']), ('\u32a6',
- &['\u4e0b']), ('\u32a7', &['\u5de6']), ('\u32a8', &['\u53f3']), ('\u32a9', &['\u533b']),
- ('\u32aa', &['\u5b97']), ('\u32ab', &['\u5b66']), ('\u32ac', &['\u76e3']), ('\u32ad',
- &['\u4f01']), ('\u32ae', &['\u8cc7']), ('\u32af', &['\u5354']), ('\u32b0', &['\u591c']),
- ('\u32b1', &['\x33', '\x36']), ('\u32b2', &['\x33', '\x37']), ('\u32b3', &['\x33', '\x38']),
- ('\u32b4', &['\x33', '\x39']), ('\u32b5', &['\x34', '\x30']), ('\u32b6', &['\x34', '\x31']),
- ('\u32b7', &['\x34', '\x32']), ('\u32b8', &['\x34', '\x33']), ('\u32b9', &['\x34', '\x34']),
- ('\u32ba', &['\x34', '\x35']), ('\u32bb', &['\x34', '\x36']), ('\u32bc', &['\x34', '\x37']),
- ('\u32bd', &['\x34', '\x38']), ('\u32be', &['\x34', '\x39']), ('\u32bf', &['\x35', '\x30']),
- ('\u32c0', &['\x31', '\u6708']), ('\u32c1', &['\x32', '\u6708']), ('\u32c2', &['\x33',
- '\u6708']), ('\u32c3', &['\x34', '\u6708']), ('\u32c4', &['\x35', '\u6708']), ('\u32c5',
- &['\x36', '\u6708']), ('\u32c6', &['\x37', '\u6708']), ('\u32c7', &['\x38', '\u6708']),
- ('\u32c8', &['\x39', '\u6708']), ('\u32c9', &['\x31', '\x30', '\u6708']), ('\u32ca',
- &['\x31', '\x31', '\u6708']), ('\u32cb', &['\x31', '\x32', '\u6708']), ('\u32cc', &['\x48',
- '\x67']), ('\u32cd', &['\x65', '\x72', '\x67']), ('\u32ce', &['\x65', '\x56']), ('\u32cf',
- &['\x4c', '\x54', '\x44']), ('\u32d0', &['\u30a2']), ('\u32d1', &['\u30a4']), ('\u32d2',
- &['\u30a6']), ('\u32d3', &['\u30a8']), ('\u32d4', &['\u30aa']), ('\u32d5', &['\u30ab']),
- ('\u32d6', &['\u30ad']), ('\u32d7', &['\u30af']), ('\u32d8', &['\u30b1']), ('\u32d9',
- &['\u30b3']), ('\u32da', &['\u30b5']), ('\u32db', &['\u30b7']), ('\u32dc', &['\u30b9']),
- ('\u32dd', &['\u30bb']), ('\u32de', &['\u30bd']), ('\u32df', &['\u30bf']), ('\u32e0',
- &['\u30c1']), ('\u32e1', &['\u30c4']), ('\u32e2', &['\u30c6']), ('\u32e3', &['\u30c8']),
- ('\u32e4', &['\u30ca']), ('\u32e5', &['\u30cb']), ('\u32e6', &['\u30cc']), ('\u32e7',
- &['\u30cd']), ('\u32e8', &['\u30ce']), ('\u32e9', &['\u30cf']), ('\u32ea', &['\u30d2']),
- ('\u32eb', &['\u30d5']), ('\u32ec', &['\u30d8']), ('\u32ed', &['\u30db']), ('\u32ee',
- &['\u30de']), ('\u32ef', &['\u30df']), ('\u32f0', &['\u30e0']), ('\u32f1', &['\u30e1']),
- ('\u32f2', &['\u30e2']), ('\u32f3', &['\u30e4']), ('\u32f4', &['\u30e6']), ('\u32f5',
- &['\u30e8']), ('\u32f6', &['\u30e9']), ('\u32f7', &['\u30ea']), ('\u32f8', &['\u30eb']),
- ('\u32f9', &['\u30ec']), ('\u32fa', &['\u30ed']), ('\u32fb', &['\u30ef']), ('\u32fc',
- &['\u30f0']), ('\u32fd', &['\u30f1']), ('\u32fe', &['\u30f2']), ('\u3300', &['\u30a2',
- '\u30d1', '\u30fc', '\u30c8']), ('\u3301', &['\u30a2', '\u30eb', '\u30d5', '\u30a1']),
- ('\u3302', &['\u30a2', '\u30f3', '\u30da', '\u30a2']), ('\u3303', &['\u30a2', '\u30fc',
- '\u30eb']), ('\u3304', &['\u30a4', '\u30cb', '\u30f3', '\u30b0']), ('\u3305', &['\u30a4',
- '\u30f3', '\u30c1']), ('\u3306', &['\u30a6', '\u30a9', '\u30f3']), ('\u3307', &['\u30a8',
- '\u30b9', '\u30af', '\u30fc', '\u30c9']), ('\u3308', &['\u30a8', '\u30fc', '\u30ab',
- '\u30fc']), ('\u3309', &['\u30aa', '\u30f3', '\u30b9']), ('\u330a', &['\u30aa', '\u30fc',
- '\u30e0']), ('\u330b', &['\u30ab', '\u30a4', '\u30ea']), ('\u330c', &['\u30ab', '\u30e9',
- '\u30c3', '\u30c8']), ('\u330d', &['\u30ab', '\u30ed', '\u30ea', '\u30fc']), ('\u330e',
- &['\u30ac', '\u30ed', '\u30f3']), ('\u330f', &['\u30ac', '\u30f3', '\u30de']), ('\u3310',
- &['\u30ae', '\u30ac']), ('\u3311', &['\u30ae', '\u30cb', '\u30fc']), ('\u3312', &['\u30ad',
- '\u30e5', '\u30ea', '\u30fc']), ('\u3313', &['\u30ae', '\u30eb', '\u30c0', '\u30fc']),
- ('\u3314', &['\u30ad', '\u30ed']), ('\u3315', &['\u30ad', '\u30ed', '\u30b0', '\u30e9',
- '\u30e0']), ('\u3316', &['\u30ad', '\u30ed', '\u30e1', '\u30fc', '\u30c8', '\u30eb']),
- ('\u3317', &['\u30ad', '\u30ed', '\u30ef', '\u30c3', '\u30c8']), ('\u3318', &['\u30b0',
- '\u30e9', '\u30e0']), ('\u3319', &['\u30b0', '\u30e9', '\u30e0', '\u30c8', '\u30f3']),
- ('\u331a', &['\u30af', '\u30eb', '\u30bc', '\u30a4', '\u30ed']), ('\u331b', &['\u30af',
- '\u30ed', '\u30fc', '\u30cd']), ('\u331c', &['\u30b1', '\u30fc', '\u30b9']), ('\u331d',
- &['\u30b3', '\u30eb', '\u30ca']), ('\u331e', &['\u30b3', '\u30fc', '\u30dd']), ('\u331f',
- &['\u30b5', '\u30a4', '\u30af', '\u30eb']), ('\u3320', &['\u30b5', '\u30f3', '\u30c1',
- '\u30fc', '\u30e0']), ('\u3321', &['\u30b7', '\u30ea', '\u30f3', '\u30b0']), ('\u3322',
- &['\u30bb', '\u30f3', '\u30c1']), ('\u3323', &['\u30bb', '\u30f3', '\u30c8']), ('\u3324',
- &['\u30c0', '\u30fc', '\u30b9']), ('\u3325', &['\u30c7', '\u30b7']), ('\u3326', &['\u30c9',
- '\u30eb']), ('\u3327', &['\u30c8', '\u30f3']), ('\u3328', &['\u30ca', '\u30ce']), ('\u3329',
- &['\u30ce', '\u30c3', '\u30c8']), ('\u332a', &['\u30cf', '\u30a4', '\u30c4']), ('\u332b',
- &['\u30d1', '\u30fc', '\u30bb', '\u30f3', '\u30c8']), ('\u332c', &['\u30d1', '\u30fc',
- '\u30c4']), ('\u332d', &['\u30d0', '\u30fc', '\u30ec', '\u30eb']), ('\u332e', &['\u30d4',
- '\u30a2', '\u30b9', '\u30c8', '\u30eb']), ('\u332f', &['\u30d4', '\u30af', '\u30eb']),
- ('\u3330', &['\u30d4', '\u30b3']), ('\u3331', &['\u30d3', '\u30eb']), ('\u3332', &['\u30d5',
- '\u30a1', '\u30e9', '\u30c3', '\u30c9']), ('\u3333', &['\u30d5', '\u30a3', '\u30fc',
- '\u30c8']), ('\u3334', &['\u30d6', '\u30c3', '\u30b7', '\u30a7', '\u30eb']), ('\u3335',
- &['\u30d5', '\u30e9', '\u30f3']), ('\u3336', &['\u30d8', '\u30af', '\u30bf', '\u30fc',
- '\u30eb']), ('\u3337', &['\u30da', '\u30bd']), ('\u3338', &['\u30da', '\u30cb', '\u30d2']),
- ('\u3339', &['\u30d8', '\u30eb', '\u30c4']), ('\u333a', &['\u30da', '\u30f3', '\u30b9']),
- ('\u333b', &['\u30da', '\u30fc', '\u30b8']), ('\u333c', &['\u30d9', '\u30fc', '\u30bf']),
- ('\u333d', &['\u30dd', '\u30a4', '\u30f3', '\u30c8']), ('\u333e', &['\u30dc', '\u30eb',
- '\u30c8']), ('\u333f', &['\u30db', '\u30f3']), ('\u3340', &['\u30dd', '\u30f3', '\u30c9']),
- ('\u3341', &['\u30db', '\u30fc', '\u30eb']), ('\u3342', &['\u30db', '\u30fc', '\u30f3']),
- ('\u3343', &['\u30de', '\u30a4', '\u30af', '\u30ed']), ('\u3344', &['\u30de', '\u30a4',
- '\u30eb']), ('\u3345', &['\u30de', '\u30c3', '\u30cf']), ('\u3346', &['\u30de', '\u30eb',
- '\u30af']), ('\u3347', &['\u30de', '\u30f3', '\u30b7', '\u30e7', '\u30f3']), ('\u3348',
- &['\u30df', '\u30af', '\u30ed', '\u30f3']), ('\u3349', &['\u30df', '\u30ea']), ('\u334a',
- &['\u30df', '\u30ea', '\u30d0', '\u30fc', '\u30eb']), ('\u334b', &['\u30e1', '\u30ac']),
- ('\u334c', &['\u30e1', '\u30ac', '\u30c8', '\u30f3']), ('\u334d', &['\u30e1', '\u30fc',
- '\u30c8', '\u30eb']), ('\u334e', &['\u30e4', '\u30fc', '\u30c9']), ('\u334f', &['\u30e4',
- '\u30fc', '\u30eb']), ('\u3350', &['\u30e6', '\u30a2', '\u30f3']), ('\u3351', &['\u30ea',
- '\u30c3', '\u30c8', '\u30eb']), ('\u3352', &['\u30ea', '\u30e9']), ('\u3353', &['\u30eb',
- '\u30d4', '\u30fc']), ('\u3354', &['\u30eb', '\u30fc', '\u30d6', '\u30eb']), ('\u3355',
- &['\u30ec', '\u30e0']), ('\u3356', &['\u30ec', '\u30f3', '\u30c8', '\u30b2', '\u30f3']),
- ('\u3357', &['\u30ef', '\u30c3', '\u30c8']), ('\u3358', &['\x30', '\u70b9']), ('\u3359',
- &['\x31', '\u70b9']), ('\u335a', &['\x32', '\u70b9']), ('\u335b', &['\x33', '\u70b9']),
- ('\u335c', &['\x34', '\u70b9']), ('\u335d', &['\x35', '\u70b9']), ('\u335e', &['\x36',
- '\u70b9']), ('\u335f', &['\x37', '\u70b9']), ('\u3360', &['\x38', '\u70b9']), ('\u3361',
- &['\x39', '\u70b9']), ('\u3362', &['\x31', '\x30', '\u70b9']), ('\u3363', &['\x31', '\x31',
- '\u70b9']), ('\u3364', &['\x31', '\x32', '\u70b9']), ('\u3365', &['\x31', '\x33',
- '\u70b9']), ('\u3366', &['\x31', '\x34', '\u70b9']), ('\u3367', &['\x31', '\x35',
- '\u70b9']), ('\u3368', &['\x31', '\x36', '\u70b9']), ('\u3369', &['\x31', '\x37',
- '\u70b9']), ('\u336a', &['\x31', '\x38', '\u70b9']), ('\u336b', &['\x31', '\x39',
- '\u70b9']), ('\u336c', &['\x32', '\x30', '\u70b9']), ('\u336d', &['\x32', '\x31',
- '\u70b9']), ('\u336e', &['\x32', '\x32', '\u70b9']), ('\u336f', &['\x32', '\x33',
- '\u70b9']), ('\u3370', &['\x32', '\x34', '\u70b9']), ('\u3371', &['\x68', '\x50', '\x61']),
- ('\u3372', &['\x64', '\x61']), ('\u3373', &['\x41', '\x55']), ('\u3374', &['\x62', '\x61',
- '\x72']), ('\u3375', &['\x6f', '\x56']), ('\u3376', &['\x70', '\x63']), ('\u3377', &['\x64',
- '\x6d']), ('\u3378', &['\x64', '\x6d', '\xb2']), ('\u3379', &['\x64', '\x6d', '\xb3']),
- ('\u337a', &['\x49', '\x55']), ('\u337b', &['\u5e73', '\u6210']), ('\u337c', &['\u662d',
- '\u548c']), ('\u337d', &['\u5927', '\u6b63']), ('\u337e', &['\u660e', '\u6cbb']), ('\u337f',
- &['\u682a', '\u5f0f', '\u4f1a', '\u793e']), ('\u3380', &['\x70', '\x41']), ('\u3381',
- &['\x6e', '\x41']), ('\u3382', &['\u03bc', '\x41']), ('\u3383', &['\x6d', '\x41']),
- ('\u3384', &['\x6b', '\x41']), ('\u3385', &['\x4b', '\x42']), ('\u3386', &['\x4d', '\x42']),
- ('\u3387', &['\x47', '\x42']), ('\u3388', &['\x63', '\x61', '\x6c']), ('\u3389', &['\x6b',
- '\x63', '\x61', '\x6c']), ('\u338a', &['\x70', '\x46']), ('\u338b', &['\x6e', '\x46']),
- ('\u338c', &['\u03bc', '\x46']), ('\u338d', &['\u03bc', '\x67']), ('\u338e', &['\x6d',
- '\x67']), ('\u338f', &['\x6b', '\x67']), ('\u3390', &['\x48', '\x7a']), ('\u3391', &['\x6b',
- '\x48', '\x7a']), ('\u3392', &['\x4d', '\x48', '\x7a']), ('\u3393', &['\x47', '\x48',
- '\x7a']), ('\u3394', &['\x54', '\x48', '\x7a']), ('\u3395', &['\u03bc', '\u2113']),
- ('\u3396', &['\x6d', '\u2113']), ('\u3397', &['\x64', '\u2113']), ('\u3398', &['\x6b',
- '\u2113']), ('\u3399', &['\x66', '\x6d']), ('\u339a', &['\x6e', '\x6d']), ('\u339b',
- &['\u03bc', '\x6d']), ('\u339c', &['\x6d', '\x6d']), ('\u339d', &['\x63', '\x6d']),
- ('\u339e', &['\x6b', '\x6d']), ('\u339f', &['\x6d', '\x6d', '\xb2']), ('\u33a0', &['\x63',
- '\x6d', '\xb2']), ('\u33a1', &['\x6d', '\xb2']), ('\u33a2', &['\x6b', '\x6d', '\xb2']),
- ('\u33a3', &['\x6d', '\x6d', '\xb3']), ('\u33a4', &['\x63', '\x6d', '\xb3']), ('\u33a5',
- &['\x6d', '\xb3']), ('\u33a6', &['\x6b', '\x6d', '\xb3']), ('\u33a7', &['\x6d', '\u2215',
- '\x73']), ('\u33a8', &['\x6d', '\u2215', '\x73', '\xb2']), ('\u33a9', &['\x50', '\x61']),
- ('\u33aa', &['\x6b', '\x50', '\x61']), ('\u33ab', &['\x4d', '\x50', '\x61']), ('\u33ac',
- &['\x47', '\x50', '\x61']), ('\u33ad', &['\x72', '\x61', '\x64']), ('\u33ae', &['\x72',
- '\x61', '\x64', '\u2215', '\x73']), ('\u33af', &['\x72', '\x61', '\x64', '\u2215', '\x73',
- '\xb2']), ('\u33b0', &['\x70', '\x73']), ('\u33b1', &['\x6e', '\x73']), ('\u33b2',
- &['\u03bc', '\x73']), ('\u33b3', &['\x6d', '\x73']), ('\u33b4', &['\x70', '\x56']),
- ('\u33b5', &['\x6e', '\x56']), ('\u33b6', &['\u03bc', '\x56']), ('\u33b7', &['\x6d',
- '\x56']), ('\u33b8', &['\x6b', '\x56']), ('\u33b9', &['\x4d', '\x56']), ('\u33ba', &['\x70',
- '\x57']), ('\u33bb', &['\x6e', '\x57']), ('\u33bc', &['\u03bc', '\x57']), ('\u33bd',
- &['\x6d', '\x57']), ('\u33be', &['\x6b', '\x57']), ('\u33bf', &['\x4d', '\x57']), ('\u33c0',
- &['\x6b', '\u03a9']), ('\u33c1', &['\x4d', '\u03a9']), ('\u33c2', &['\x61', '\x2e', '\x6d',
- '\x2e']), ('\u33c3', &['\x42', '\x71']), ('\u33c4', &['\x63', '\x63']), ('\u33c5', &['\x63',
- '\x64']), ('\u33c6', &['\x43', '\u2215', '\x6b', '\x67']), ('\u33c7', &['\x43', '\x6f',
- '\x2e']), ('\u33c8', &['\x64', '\x42']), ('\u33c9', &['\x47', '\x79']), ('\u33ca', &['\x68',
- '\x61']), ('\u33cb', &['\x48', '\x50']), ('\u33cc', &['\x69', '\x6e']), ('\u33cd', &['\x4b',
- '\x4b']), ('\u33ce', &['\x4b', '\x4d']), ('\u33cf', &['\x6b', '\x74']), ('\u33d0', &['\x6c',
- '\x6d']), ('\u33d1', &['\x6c', '\x6e']), ('\u33d2', &['\x6c', '\x6f', '\x67']), ('\u33d3',
- &['\x6c', '\x78']), ('\u33d4', &['\x6d', '\x62']), ('\u33d5', &['\x6d', '\x69', '\x6c']),
- ('\u33d6', &['\x6d', '\x6f', '\x6c']), ('\u33d7', &['\x50', '\x48']), ('\u33d8', &['\x70',
- '\x2e', '\x6d', '\x2e']), ('\u33d9', &['\x50', '\x50', '\x4d']), ('\u33da', &['\x50',
- '\x52']), ('\u33db', &['\x73', '\x72']), ('\u33dc', &['\x53', '\x76']), ('\u33dd', &['\x57',
- '\x62']), ('\u33de', &['\x56', '\u2215', '\x6d']), ('\u33df', &['\x41', '\u2215', '\x6d']),
- ('\u33e0', &['\x31', '\u65e5']), ('\u33e1', &['\x32', '\u65e5']), ('\u33e2', &['\x33',
- '\u65e5']), ('\u33e3', &['\x34', '\u65e5']), ('\u33e4', &['\x35', '\u65e5']), ('\u33e5',
- &['\x36', '\u65e5']), ('\u33e6', &['\x37', '\u65e5']), ('\u33e7', &['\x38', '\u65e5']),
- ('\u33e8', &['\x39', '\u65e5']), ('\u33e9', &['\x31', '\x30', '\u65e5']), ('\u33ea',
- &['\x31', '\x31', '\u65e5']), ('\u33eb', &['\x31', '\x32', '\u65e5']), ('\u33ec', &['\x31',
- '\x33', '\u65e5']), ('\u33ed', &['\x31', '\x34', '\u65e5']), ('\u33ee', &['\x31', '\x35',
- '\u65e5']), ('\u33ef', &['\x31', '\x36', '\u65e5']), ('\u33f0', &['\x31', '\x37',
- '\u65e5']), ('\u33f1', &['\x31', '\x38', '\u65e5']), ('\u33f2', &['\x31', '\x39',
- '\u65e5']), ('\u33f3', &['\x32', '\x30', '\u65e5']), ('\u33f4', &['\x32', '\x31',
- '\u65e5']), ('\u33f5', &['\x32', '\x32', '\u65e5']), ('\u33f6', &['\x32', '\x33',
- '\u65e5']), ('\u33f7', &['\x32', '\x34', '\u65e5']), ('\u33f8', &['\x32', '\x35',
- '\u65e5']), ('\u33f9', &['\x32', '\x36', '\u65e5']), ('\u33fa', &['\x32', '\x37',
- '\u65e5']), ('\u33fb', &['\x32', '\x38', '\u65e5']), ('\u33fc', &['\x32', '\x39',
- '\u65e5']), ('\u33fd', &['\x33', '\x30', '\u65e5']), ('\u33fe', &['\x33', '\x31',
- '\u65e5']), ('\u33ff', &['\x67', '\x61', '\x6c']), ('\ua770', &['\ua76f']), ('\ua7f8',
- &['\u0126']), ('\ua7f9', &['\u0153']), ('\ufb00', &['\x66', '\x66']), ('\ufb01', &['\x66',
- '\x69']), ('\ufb02', &['\x66', '\x6c']), ('\ufb03', &['\x66', '\x66', '\x69']), ('\ufb04',
- &['\x66', '\x66', '\x6c']), ('\ufb05', &['\u017f', '\x74']), ('\ufb06', &['\x73', '\x74']),
- ('\ufb13', &['\u0574', '\u0576']), ('\ufb14', &['\u0574', '\u0565']), ('\ufb15', &['\u0574',
- '\u056b']), ('\ufb16', &['\u057e', '\u0576']), ('\ufb17', &['\u0574', '\u056d']), ('\ufb20',
- &['\u05e2']), ('\ufb21', &['\u05d0']), ('\ufb22', &['\u05d3']), ('\ufb23', &['\u05d4']),
- ('\ufb24', &['\u05db']), ('\ufb25', &['\u05dc']), ('\ufb26', &['\u05dd']), ('\ufb27',
- &['\u05e8']), ('\ufb28', &['\u05ea']), ('\ufb29', &['\x2b']), ('\ufb4f', &['\u05d0',
- '\u05dc']), ('\ufb50', &['\u0671']), ('\ufb51', &['\u0671']), ('\ufb52', &['\u067b']),
- ('\ufb53', &['\u067b']), ('\ufb54', &['\u067b']), ('\ufb55', &['\u067b']), ('\ufb56',
- &['\u067e']), ('\ufb57', &['\u067e']), ('\ufb58', &['\u067e']), ('\ufb59', &['\u067e']),
- ('\ufb5a', &['\u0680']), ('\ufb5b', &['\u0680']), ('\ufb5c', &['\u0680']), ('\ufb5d',
- &['\u0680']), ('\ufb5e', &['\u067a']), ('\ufb5f', &['\u067a']), ('\ufb60', &['\u067a']),
- ('\ufb61', &['\u067a']), ('\ufb62', &['\u067f']), ('\ufb63', &['\u067f']), ('\ufb64',
- &['\u067f']), ('\ufb65', &['\u067f']), ('\ufb66', &['\u0679']), ('\ufb67', &['\u0679']),
- ('\ufb68', &['\u0679']), ('\ufb69', &['\u0679']), ('\ufb6a', &['\u06a4']), ('\ufb6b',
- &['\u06a4']), ('\ufb6c', &['\u06a4']), ('\ufb6d', &['\u06a4']), ('\ufb6e', &['\u06a6']),
- ('\ufb6f', &['\u06a6']), ('\ufb70', &['\u06a6']), ('\ufb71', &['\u06a6']), ('\ufb72',
- &['\u0684']), ('\ufb73', &['\u0684']), ('\ufb74', &['\u0684']), ('\ufb75', &['\u0684']),
- ('\ufb76', &['\u0683']), ('\ufb77', &['\u0683']), ('\ufb78', &['\u0683']), ('\ufb79',
- &['\u0683']), ('\ufb7a', &['\u0686']), ('\ufb7b', &['\u0686']), ('\ufb7c', &['\u0686']),
- ('\ufb7d', &['\u0686']), ('\ufb7e', &['\u0687']), ('\ufb7f', &['\u0687']), ('\ufb80',
- &['\u0687']), ('\ufb81', &['\u0687']), ('\ufb82', &['\u068d']), ('\ufb83', &['\u068d']),
- ('\ufb84', &['\u068c']), ('\ufb85', &['\u068c']), ('\ufb86', &['\u068e']), ('\ufb87',
- &['\u068e']), ('\ufb88', &['\u0688']), ('\ufb89', &['\u0688']), ('\ufb8a', &['\u0698']),
- ('\ufb8b', &['\u0698']), ('\ufb8c', &['\u0691']), ('\ufb8d', &['\u0691']), ('\ufb8e',
- &['\u06a9']), ('\ufb8f', &['\u06a9']), ('\ufb90', &['\u06a9']), ('\ufb91', &['\u06a9']),
- ('\ufb92', &['\u06af']), ('\ufb93', &['\u06af']), ('\ufb94', &['\u06af']), ('\ufb95',
- &['\u06af']), ('\ufb96', &['\u06b3']), ('\ufb97', &['\u06b3']), ('\ufb98', &['\u06b3']),
- ('\ufb99', &['\u06b3']), ('\ufb9a', &['\u06b1']), ('\ufb9b', &['\u06b1']), ('\ufb9c',
- &['\u06b1']), ('\ufb9d', &['\u06b1']), ('\ufb9e', &['\u06ba']), ('\ufb9f', &['\u06ba']),
- ('\ufba0', &['\u06bb']), ('\ufba1', &['\u06bb']), ('\ufba2', &['\u06bb']), ('\ufba3',
- &['\u06bb']), ('\ufba4', &['\u06c0']), ('\ufba5', &['\u06c0']), ('\ufba6', &['\u06c1']),
- ('\ufba7', &['\u06c1']), ('\ufba8', &['\u06c1']), ('\ufba9', &['\u06c1']), ('\ufbaa',
- &['\u06be']), ('\ufbab', &['\u06be']), ('\ufbac', &['\u06be']), ('\ufbad', &['\u06be']),
- ('\ufbae', &['\u06d2']), ('\ufbaf', &['\u06d2']), ('\ufbb0', &['\u06d3']), ('\ufbb1',
- &['\u06d3']), ('\ufbd3', &['\u06ad']), ('\ufbd4', &['\u06ad']), ('\ufbd5', &['\u06ad']),
- ('\ufbd6', &['\u06ad']), ('\ufbd7', &['\u06c7']), ('\ufbd8', &['\u06c7']), ('\ufbd9',
- &['\u06c6']), ('\ufbda', &['\u06c6']), ('\ufbdb', &['\u06c8']), ('\ufbdc', &['\u06c8']),
- ('\ufbdd', &['\u0677']), ('\ufbde', &['\u06cb']), ('\ufbdf', &['\u06cb']), ('\ufbe0',
- &['\u06c5']), ('\ufbe1', &['\u06c5']), ('\ufbe2', &['\u06c9']), ('\ufbe3', &['\u06c9']),
- ('\ufbe4', &['\u06d0']), ('\ufbe5', &['\u06d0']), ('\ufbe6', &['\u06d0']), ('\ufbe7',
- &['\u06d0']), ('\ufbe8', &['\u0649']), ('\ufbe9', &['\u0649']), ('\ufbea', &['\u0626',
- '\u0627']), ('\ufbeb', &['\u0626', '\u0627']), ('\ufbec', &['\u0626', '\u06d5']), ('\ufbed',
- &['\u0626', '\u06d5']), ('\ufbee', &['\u0626', '\u0648']), ('\ufbef', &['\u0626',
- '\u0648']), ('\ufbf0', &['\u0626', '\u06c7']), ('\ufbf1', &['\u0626', '\u06c7']), ('\ufbf2',
- &['\u0626', '\u06c6']), ('\ufbf3', &['\u0626', '\u06c6']), ('\ufbf4', &['\u0626',
- '\u06c8']), ('\ufbf5', &['\u0626', '\u06c8']), ('\ufbf6', &['\u0626', '\u06d0']), ('\ufbf7',
- &['\u0626', '\u06d0']), ('\ufbf8', &['\u0626', '\u06d0']), ('\ufbf9', &['\u0626',
- '\u0649']), ('\ufbfa', &['\u0626', '\u0649']), ('\ufbfb', &['\u0626', '\u0649']), ('\ufbfc',
- &['\u06cc']), ('\ufbfd', &['\u06cc']), ('\ufbfe', &['\u06cc']), ('\ufbff', &['\u06cc']),
- ('\ufc00', &['\u0626', '\u062c']), ('\ufc01', &['\u0626', '\u062d']), ('\ufc02', &['\u0626',
- '\u0645']), ('\ufc03', &['\u0626', '\u0649']), ('\ufc04', &['\u0626', '\u064a']), ('\ufc05',
- &['\u0628', '\u062c']), ('\ufc06', &['\u0628', '\u062d']), ('\ufc07', &['\u0628',
- '\u062e']), ('\ufc08', &['\u0628', '\u0645']), ('\ufc09', &['\u0628', '\u0649']), ('\ufc0a',
- &['\u0628', '\u064a']), ('\ufc0b', &['\u062a', '\u062c']), ('\ufc0c', &['\u062a',
- '\u062d']), ('\ufc0d', &['\u062a', '\u062e']), ('\ufc0e', &['\u062a', '\u0645']), ('\ufc0f',
- &['\u062a', '\u0649']), ('\ufc10', &['\u062a', '\u064a']), ('\ufc11', &['\u062b',
- '\u062c']), ('\ufc12', &['\u062b', '\u0645']), ('\ufc13', &['\u062b', '\u0649']), ('\ufc14',
- &['\u062b', '\u064a']), ('\ufc15', &['\u062c', '\u062d']), ('\ufc16', &['\u062c',
- '\u0645']), ('\ufc17', &['\u062d', '\u062c']), ('\ufc18', &['\u062d', '\u0645']), ('\ufc19',
- &['\u062e', '\u062c']), ('\ufc1a', &['\u062e', '\u062d']), ('\ufc1b', &['\u062e',
- '\u0645']), ('\ufc1c', &['\u0633', '\u062c']), ('\ufc1d', &['\u0633', '\u062d']), ('\ufc1e',
- &['\u0633', '\u062e']), ('\ufc1f', &['\u0633', '\u0645']), ('\ufc20', &['\u0635',
- '\u062d']), ('\ufc21', &['\u0635', '\u0645']), ('\ufc22', &['\u0636', '\u062c']), ('\ufc23',
- &['\u0636', '\u062d']), ('\ufc24', &['\u0636', '\u062e']), ('\ufc25', &['\u0636',
- '\u0645']), ('\ufc26', &['\u0637', '\u062d']), ('\ufc27', &['\u0637', '\u0645']), ('\ufc28',
- &['\u0638', '\u0645']), ('\ufc29', &['\u0639', '\u062c']), ('\ufc2a', &['\u0639',
- '\u0645']), ('\ufc2b', &['\u063a', '\u062c']), ('\ufc2c', &['\u063a', '\u0645']), ('\ufc2d',
- &['\u0641', '\u062c']), ('\ufc2e', &['\u0641', '\u062d']), ('\ufc2f', &['\u0641',
- '\u062e']), ('\ufc30', &['\u0641', '\u0645']), ('\ufc31', &['\u0641', '\u0649']), ('\ufc32',
- &['\u0641', '\u064a']), ('\ufc33', &['\u0642', '\u062d']), ('\ufc34', &['\u0642',
- '\u0645']), ('\ufc35', &['\u0642', '\u0649']), ('\ufc36', &['\u0642', '\u064a']), ('\ufc37',
- &['\u0643', '\u0627']), ('\ufc38', &['\u0643', '\u062c']), ('\ufc39', &['\u0643',
- '\u062d']), ('\ufc3a', &['\u0643', '\u062e']), ('\ufc3b', &['\u0643', '\u0644']), ('\ufc3c',
- &['\u0643', '\u0645']), ('\ufc3d', &['\u0643', '\u0649']), ('\ufc3e', &['\u0643',
- '\u064a']), ('\ufc3f', &['\u0644', '\u062c']), ('\ufc40', &['\u0644', '\u062d']), ('\ufc41',
- &['\u0644', '\u062e']), ('\ufc42', &['\u0644', '\u0645']), ('\ufc43', &['\u0644',
- '\u0649']), ('\ufc44', &['\u0644', '\u064a']), ('\ufc45', &['\u0645', '\u062c']), ('\ufc46',
- &['\u0645', '\u062d']), ('\ufc47', &['\u0645', '\u062e']), ('\ufc48', &['\u0645',
- '\u0645']), ('\ufc49', &['\u0645', '\u0649']), ('\ufc4a', &['\u0645', '\u064a']), ('\ufc4b',
- &['\u0646', '\u062c']), ('\ufc4c', &['\u0646', '\u062d']), ('\ufc4d', &['\u0646',
- '\u062e']), ('\ufc4e', &['\u0646', '\u0645']), ('\ufc4f', &['\u0646', '\u0649']), ('\ufc50',
- &['\u0646', '\u064a']), ('\ufc51', &['\u0647', '\u062c']), ('\ufc52', &['\u0647',
- '\u0645']), ('\ufc53', &['\u0647', '\u0649']), ('\ufc54', &['\u0647', '\u064a']), ('\ufc55',
- &['\u064a', '\u062c']), ('\ufc56', &['\u064a', '\u062d']), ('\ufc57', &['\u064a',
- '\u062e']), ('\ufc58', &['\u064a', '\u0645']), ('\ufc59', &['\u064a', '\u0649']), ('\ufc5a',
- &['\u064a', '\u064a']), ('\ufc5b', &['\u0630', '\u0670']), ('\ufc5c', &['\u0631',
- '\u0670']), ('\ufc5d', &['\u0649', '\u0670']), ('\ufc5e', &['\x20', '\u064c', '\u0651']),
- ('\ufc5f', &['\x20', '\u064d', '\u0651']), ('\ufc60', &['\x20', '\u064e', '\u0651']),
- ('\ufc61', &['\x20', '\u064f', '\u0651']), ('\ufc62', &['\x20', '\u0650', '\u0651']),
- ('\ufc63', &['\x20', '\u0651', '\u0670']), ('\ufc64', &['\u0626', '\u0631']), ('\ufc65',
- &['\u0626', '\u0632']), ('\ufc66', &['\u0626', '\u0645']), ('\ufc67', &['\u0626',
- '\u0646']), ('\ufc68', &['\u0626', '\u0649']), ('\ufc69', &['\u0626', '\u064a']), ('\ufc6a',
- &['\u0628', '\u0631']), ('\ufc6b', &['\u0628', '\u0632']), ('\ufc6c', &['\u0628',
- '\u0645']), ('\ufc6d', &['\u0628', '\u0646']), ('\ufc6e', &['\u0628', '\u0649']), ('\ufc6f',
- &['\u0628', '\u064a']), ('\ufc70', &['\u062a', '\u0631']), ('\ufc71', &['\u062a',
- '\u0632']), ('\ufc72', &['\u062a', '\u0645']), ('\ufc73', &['\u062a', '\u0646']), ('\ufc74',
- &['\u062a', '\u0649']), ('\ufc75', &['\u062a', '\u064a']), ('\ufc76', &['\u062b',
- '\u0631']), ('\ufc77', &['\u062b', '\u0632']), ('\ufc78', &['\u062b', '\u0645']), ('\ufc79',
- &['\u062b', '\u0646']), ('\ufc7a', &['\u062b', '\u0649']), ('\ufc7b', &['\u062b',
- '\u064a']), ('\ufc7c', &['\u0641', '\u0649']), ('\ufc7d', &['\u0641', '\u064a']), ('\ufc7e',
- &['\u0642', '\u0649']), ('\ufc7f', &['\u0642', '\u064a']), ('\ufc80', &['\u0643',
- '\u0627']), ('\ufc81', &['\u0643', '\u0644']), ('\ufc82', &['\u0643', '\u0645']), ('\ufc83',
- &['\u0643', '\u0649']), ('\ufc84', &['\u0643', '\u064a']), ('\ufc85', &['\u0644',
- '\u0645']), ('\ufc86', &['\u0644', '\u0649']), ('\ufc87', &['\u0644', '\u064a']), ('\ufc88',
- &['\u0645', '\u0627']), ('\ufc89', &['\u0645', '\u0645']), ('\ufc8a', &['\u0646',
- '\u0631']), ('\ufc8b', &['\u0646', '\u0632']), ('\ufc8c', &['\u0646', '\u0645']), ('\ufc8d',
- &['\u0646', '\u0646']), ('\ufc8e', &['\u0646', '\u0649']), ('\ufc8f', &['\u0646',
- '\u064a']), ('\ufc90', &['\u0649', '\u0670']), ('\ufc91', &['\u064a', '\u0631']), ('\ufc92',
- &['\u064a', '\u0632']), ('\ufc93', &['\u064a', '\u0645']), ('\ufc94', &['\u064a',
- '\u0646']), ('\ufc95', &['\u064a', '\u0649']), ('\ufc96', &['\u064a', '\u064a']), ('\ufc97',
- &['\u0626', '\u062c']), ('\ufc98', &['\u0626', '\u062d']), ('\ufc99', &['\u0626',
- '\u062e']), ('\ufc9a', &['\u0626', '\u0645']), ('\ufc9b', &['\u0626', '\u0647']), ('\ufc9c',
- &['\u0628', '\u062c']), ('\ufc9d', &['\u0628', '\u062d']), ('\ufc9e', &['\u0628',
- '\u062e']), ('\ufc9f', &['\u0628', '\u0645']), ('\ufca0', &['\u0628', '\u0647']), ('\ufca1',
- &['\u062a', '\u062c']), ('\ufca2', &['\u062a', '\u062d']), ('\ufca3', &['\u062a',
- '\u062e']), ('\ufca4', &['\u062a', '\u0645']), ('\ufca5', &['\u062a', '\u0647']), ('\ufca6',
- &['\u062b', '\u0645']), ('\ufca7', &['\u062c', '\u062d']), ('\ufca8', &['\u062c',
- '\u0645']), ('\ufca9', &['\u062d', '\u062c']), ('\ufcaa', &['\u062d', '\u0645']), ('\ufcab',
- &['\u062e', '\u062c']), ('\ufcac', &['\u062e', '\u0645']), ('\ufcad', &['\u0633',
- '\u062c']), ('\ufcae', &['\u0633', '\u062d']), ('\ufcaf', &['\u0633', '\u062e']), ('\ufcb0',
- &['\u0633', '\u0645']), ('\ufcb1', &['\u0635', '\u062d']), ('\ufcb2', &['\u0635',
- '\u062e']), ('\ufcb3', &['\u0635', '\u0645']), ('\ufcb4', &['\u0636', '\u062c']), ('\ufcb5',
- &['\u0636', '\u062d']), ('\ufcb6', &['\u0636', '\u062e']), ('\ufcb7', &['\u0636',
- '\u0645']), ('\ufcb8', &['\u0637', '\u062d']), ('\ufcb9', &['\u0638', '\u0645']), ('\ufcba',
- &['\u0639', '\u062c']), ('\ufcbb', &['\u0639', '\u0645']), ('\ufcbc', &['\u063a',
- '\u062c']), ('\ufcbd', &['\u063a', '\u0645']), ('\ufcbe', &['\u0641', '\u062c']), ('\ufcbf',
- &['\u0641', '\u062d']), ('\ufcc0', &['\u0641', '\u062e']), ('\ufcc1', &['\u0641',
- '\u0645']), ('\ufcc2', &['\u0642', '\u062d']), ('\ufcc3', &['\u0642', '\u0645']), ('\ufcc4',
- &['\u0643', '\u062c']), ('\ufcc5', &['\u0643', '\u062d']), ('\ufcc6', &['\u0643',
- '\u062e']), ('\ufcc7', &['\u0643', '\u0644']), ('\ufcc8', &['\u0643', '\u0645']), ('\ufcc9',
- &['\u0644', '\u062c']), ('\ufcca', &['\u0644', '\u062d']), ('\ufccb', &['\u0644',
- '\u062e']), ('\ufccc', &['\u0644', '\u0645']), ('\ufccd', &['\u0644', '\u0647']), ('\ufcce',
- &['\u0645', '\u062c']), ('\ufccf', &['\u0645', '\u062d']), ('\ufcd0', &['\u0645',
- '\u062e']), ('\ufcd1', &['\u0645', '\u0645']), ('\ufcd2', &['\u0646', '\u062c']), ('\ufcd3',
- &['\u0646', '\u062d']), ('\ufcd4', &['\u0646', '\u062e']), ('\ufcd5', &['\u0646',
- '\u0645']), ('\ufcd6', &['\u0646', '\u0647']), ('\ufcd7', &['\u0647', '\u062c']), ('\ufcd8',
- &['\u0647', '\u0645']), ('\ufcd9', &['\u0647', '\u0670']), ('\ufcda', &['\u064a',
- '\u062c']), ('\ufcdb', &['\u064a', '\u062d']), ('\ufcdc', &['\u064a', '\u062e']), ('\ufcdd',
- &['\u064a', '\u0645']), ('\ufcde', &['\u064a', '\u0647']), ('\ufcdf', &['\u0626',
- '\u0645']), ('\ufce0', &['\u0626', '\u0647']), ('\ufce1', &['\u0628', '\u0645']), ('\ufce2',
- &['\u0628', '\u0647']), ('\ufce3', &['\u062a', '\u0645']), ('\ufce4', &['\u062a',
- '\u0647']), ('\ufce5', &['\u062b', '\u0645']), ('\ufce6', &['\u062b', '\u0647']), ('\ufce7',
- &['\u0633', '\u0645']), ('\ufce8', &['\u0633', '\u0647']), ('\ufce9', &['\u0634',
- '\u0645']), ('\ufcea', &['\u0634', '\u0647']), ('\ufceb', &['\u0643', '\u0644']), ('\ufcec',
- &['\u0643', '\u0645']), ('\ufced', &['\u0644', '\u0645']), ('\ufcee', &['\u0646',
- '\u0645']), ('\ufcef', &['\u0646', '\u0647']), ('\ufcf0', &['\u064a', '\u0645']), ('\ufcf1',
- &['\u064a', '\u0647']), ('\ufcf2', &['\u0640', '\u064e', '\u0651']), ('\ufcf3', &['\u0640',
- '\u064f', '\u0651']), ('\ufcf4', &['\u0640', '\u0650', '\u0651']), ('\ufcf5', &['\u0637',
- '\u0649']), ('\ufcf6', &['\u0637', '\u064a']), ('\ufcf7', &['\u0639', '\u0649']), ('\ufcf8',
- &['\u0639', '\u064a']), ('\ufcf9', &['\u063a', '\u0649']), ('\ufcfa', &['\u063a',
- '\u064a']), ('\ufcfb', &['\u0633', '\u0649']), ('\ufcfc', &['\u0633', '\u064a']), ('\ufcfd',
- &['\u0634', '\u0649']), ('\ufcfe', &['\u0634', '\u064a']), ('\ufcff', &['\u062d',
- '\u0649']), ('\ufd00', &['\u062d', '\u064a']), ('\ufd01', &['\u062c', '\u0649']), ('\ufd02',
- &['\u062c', '\u064a']), ('\ufd03', &['\u062e', '\u0649']), ('\ufd04', &['\u062e',
- '\u064a']), ('\ufd05', &['\u0635', '\u0649']), ('\ufd06', &['\u0635', '\u064a']), ('\ufd07',
- &['\u0636', '\u0649']), ('\ufd08', &['\u0636', '\u064a']), ('\ufd09', &['\u0634',
- '\u062c']), ('\ufd0a', &['\u0634', '\u062d']), ('\ufd0b', &['\u0634', '\u062e']), ('\ufd0c',
- &['\u0634', '\u0645']), ('\ufd0d', &['\u0634', '\u0631']), ('\ufd0e', &['\u0633',
- '\u0631']), ('\ufd0f', &['\u0635', '\u0631']), ('\ufd10', &['\u0636', '\u0631']), ('\ufd11',
- &['\u0637', '\u0649']), ('\ufd12', &['\u0637', '\u064a']), ('\ufd13', &['\u0639',
- '\u0649']), ('\ufd14', &['\u0639', '\u064a']), ('\ufd15', &['\u063a', '\u0649']), ('\ufd16',
- &['\u063a', '\u064a']), ('\ufd17', &['\u0633', '\u0649']), ('\ufd18', &['\u0633',
- '\u064a']), ('\ufd19', &['\u0634', '\u0649']), ('\ufd1a', &['\u0634', '\u064a']), ('\ufd1b',
- &['\u062d', '\u0649']), ('\ufd1c', &['\u062d', '\u064a']), ('\ufd1d', &['\u062c',
- '\u0649']), ('\ufd1e', &['\u062c', '\u064a']), ('\ufd1f', &['\u062e', '\u0649']), ('\ufd20',
- &['\u062e', '\u064a']), ('\ufd21', &['\u0635', '\u0649']), ('\ufd22', &['\u0635',
- '\u064a']), ('\ufd23', &['\u0636', '\u0649']), ('\ufd24', &['\u0636', '\u064a']), ('\ufd25',
- &['\u0634', '\u062c']), ('\ufd26', &['\u0634', '\u062d']), ('\ufd27', &['\u0634',
- '\u062e']), ('\ufd28', &['\u0634', '\u0645']), ('\ufd29', &['\u0634', '\u0631']), ('\ufd2a',
- &['\u0633', '\u0631']), ('\ufd2b', &['\u0635', '\u0631']), ('\ufd2c', &['\u0636',
- '\u0631']), ('\ufd2d', &['\u0634', '\u062c']), ('\ufd2e', &['\u0634', '\u062d']), ('\ufd2f',
- &['\u0634', '\u062e']), ('\ufd30', &['\u0634', '\u0645']), ('\ufd31', &['\u0633',
- '\u0647']), ('\ufd32', &['\u0634', '\u0647']), ('\ufd33', &['\u0637', '\u0645']), ('\ufd34',
- &['\u0633', '\u062c']), ('\ufd35', &['\u0633', '\u062d']), ('\ufd36', &['\u0633',
- '\u062e']), ('\ufd37', &['\u0634', '\u062c']), ('\ufd38', &['\u0634', '\u062d']), ('\ufd39',
- &['\u0634', '\u062e']), ('\ufd3a', &['\u0637', '\u0645']), ('\ufd3b', &['\u0638',
- '\u0645']), ('\ufd3c', &['\u0627', '\u064b']), ('\ufd3d', &['\u0627', '\u064b']), ('\ufd50',
- &['\u062a', '\u062c', '\u0645']), ('\ufd51', &['\u062a', '\u062d', '\u062c']), ('\ufd52',
- &['\u062a', '\u062d', '\u062c']), ('\ufd53', &['\u062a', '\u062d', '\u0645']), ('\ufd54',
- &['\u062a', '\u062e', '\u0645']), ('\ufd55', &['\u062a', '\u0645', '\u062c']), ('\ufd56',
- &['\u062a', '\u0645', '\u062d']), ('\ufd57', &['\u062a', '\u0645', '\u062e']), ('\ufd58',
- &['\u062c', '\u0645', '\u062d']), ('\ufd59', &['\u062c', '\u0645', '\u062d']), ('\ufd5a',
- &['\u062d', '\u0645', '\u064a']), ('\ufd5b', &['\u062d', '\u0645', '\u0649']), ('\ufd5c',
- &['\u0633', '\u062d', '\u062c']), ('\ufd5d', &['\u0633', '\u062c', '\u062d']), ('\ufd5e',
- &['\u0633', '\u062c', '\u0649']), ('\ufd5f', &['\u0633', '\u0645', '\u062d']), ('\ufd60',
- &['\u0633', '\u0645', '\u062d']), ('\ufd61', &['\u0633', '\u0645', '\u062c']), ('\ufd62',
- &['\u0633', '\u0645', '\u0645']), ('\ufd63', &['\u0633', '\u0645', '\u0645']), ('\ufd64',
- &['\u0635', '\u062d', '\u062d']), ('\ufd65', &['\u0635', '\u062d', '\u062d']), ('\ufd66',
- &['\u0635', '\u0645', '\u0645']), ('\ufd67', &['\u0634', '\u062d', '\u0645']), ('\ufd68',
- &['\u0634', '\u062d', '\u0645']), ('\ufd69', &['\u0634', '\u062c', '\u064a']), ('\ufd6a',
- &['\u0634', '\u0645', '\u062e']), ('\ufd6b', &['\u0634', '\u0645', '\u062e']), ('\ufd6c',
- &['\u0634', '\u0645', '\u0645']), ('\ufd6d', &['\u0634', '\u0645', '\u0645']), ('\ufd6e',
- &['\u0636', '\u062d', '\u0649']), ('\ufd6f', &['\u0636', '\u062e', '\u0645']), ('\ufd70',
- &['\u0636', '\u062e', '\u0645']), ('\ufd71', &['\u0637', '\u0645', '\u062d']), ('\ufd72',
- &['\u0637', '\u0645', '\u062d']), ('\ufd73', &['\u0637', '\u0645', '\u0645']), ('\ufd74',
- &['\u0637', '\u0645', '\u064a']), ('\ufd75', &['\u0639', '\u062c', '\u0645']), ('\ufd76',
- &['\u0639', '\u0645', '\u0645']), ('\ufd77', &['\u0639', '\u0645', '\u0645']), ('\ufd78',
- &['\u0639', '\u0645', '\u0649']), ('\ufd79', &['\u063a', '\u0645', '\u0645']), ('\ufd7a',
- &['\u063a', '\u0645', '\u064a']), ('\ufd7b', &['\u063a', '\u0645', '\u0649']), ('\ufd7c',
- &['\u0641', '\u062e', '\u0645']), ('\ufd7d', &['\u0641', '\u062e', '\u0645']), ('\ufd7e',
- &['\u0642', '\u0645', '\u062d']), ('\ufd7f', &['\u0642', '\u0645', '\u0645']), ('\ufd80',
- &['\u0644', '\u062d', '\u0645']), ('\ufd81', &['\u0644', '\u062d', '\u064a']), ('\ufd82',
- &['\u0644', '\u062d', '\u0649']), ('\ufd83', &['\u0644', '\u062c', '\u062c']), ('\ufd84',
- &['\u0644', '\u062c', '\u062c']), ('\ufd85', &['\u0644', '\u062e', '\u0645']), ('\ufd86',
- &['\u0644', '\u062e', '\u0645']), ('\ufd87', &['\u0644', '\u0645', '\u062d']), ('\ufd88',
- &['\u0644', '\u0645', '\u062d']), ('\ufd89', &['\u0645', '\u062d', '\u062c']), ('\ufd8a',
- &['\u0645', '\u062d', '\u0645']), ('\ufd8b', &['\u0645', '\u062d', '\u064a']), ('\ufd8c',
- &['\u0645', '\u062c', '\u062d']), ('\ufd8d', &['\u0645', '\u062c', '\u0645']), ('\ufd8e',
- &['\u0645', '\u062e', '\u062c']), ('\ufd8f', &['\u0645', '\u062e', '\u0645']), ('\ufd92',
- &['\u0645', '\u062c', '\u062e']), ('\ufd93', &['\u0647', '\u0645', '\u062c']), ('\ufd94',
- &['\u0647', '\u0645', '\u0645']), ('\ufd95', &['\u0646', '\u062d', '\u0645']), ('\ufd96',
- &['\u0646', '\u062d', '\u0649']), ('\ufd97', &['\u0646', '\u062c', '\u0645']), ('\ufd98',
- &['\u0646', '\u062c', '\u0645']), ('\ufd99', &['\u0646', '\u062c', '\u0649']), ('\ufd9a',
- &['\u0646', '\u0645', '\u064a']), ('\ufd9b', &['\u0646', '\u0645', '\u0649']), ('\ufd9c',
- &['\u064a', '\u0645', '\u0645']), ('\ufd9d', &['\u064a', '\u0645', '\u0645']), ('\ufd9e',
- &['\u0628', '\u062e', '\u064a']), ('\ufd9f', &['\u062a', '\u062c', '\u064a']), ('\ufda0',
- &['\u062a', '\u062c', '\u0649']), ('\ufda1', &['\u062a', '\u062e', '\u064a']), ('\ufda2',
- &['\u062a', '\u062e', '\u0649']), ('\ufda3', &['\u062a', '\u0645', '\u064a']), ('\ufda4',
- &['\u062a', '\u0645', '\u0649']), ('\ufda5', &['\u062c', '\u0645', '\u064a']), ('\ufda6',
- &['\u062c', '\u062d', '\u0649']), ('\ufda7', &['\u062c', '\u0645', '\u0649']), ('\ufda8',
- &['\u0633', '\u062e', '\u0649']), ('\ufda9', &['\u0635', '\u062d', '\u064a']), ('\ufdaa',
- &['\u0634', '\u062d', '\u064a']), ('\ufdab', &['\u0636', '\u062d', '\u064a']), ('\ufdac',
- &['\u0644', '\u062c', '\u064a']), ('\ufdad', &['\u0644', '\u0645', '\u064a']), ('\ufdae',
- &['\u064a', '\u062d', '\u064a']), ('\ufdaf', &['\u064a', '\u062c', '\u064a']), ('\ufdb0',
- &['\u064a', '\u0645', '\u064a']), ('\ufdb1', &['\u0645', '\u0645', '\u064a']), ('\ufdb2',
- &['\u0642', '\u0645', '\u064a']), ('\ufdb3', &['\u0646', '\u062d', '\u064a']), ('\ufdb4',
- &['\u0642', '\u0645', '\u062d']), ('\ufdb5', &['\u0644', '\u062d', '\u0645']), ('\ufdb6',
- &['\u0639', '\u0645', '\u064a']), ('\ufdb7', &['\u0643', '\u0645', '\u064a']), ('\ufdb8',
- &['\u0646', '\u062c', '\u062d']), ('\ufdb9', &['\u0645', '\u062e', '\u064a']), ('\ufdba',
- &['\u0644', '\u062c', '\u0645']), ('\ufdbb', &['\u0643', '\u0645', '\u0645']), ('\ufdbc',
- &['\u0644', '\u062c', '\u0645']), ('\ufdbd', &['\u0646', '\u062c', '\u062d']), ('\ufdbe',
- &['\u062c', '\u062d', '\u064a']), ('\ufdbf', &['\u062d', '\u062c', '\u064a']), ('\ufdc0',
- &['\u0645', '\u062c', '\u064a']), ('\ufdc1', &['\u0641', '\u0645', '\u064a']), ('\ufdc2',
- &['\u0628', '\u062d', '\u064a']), ('\ufdc3', &['\u0643', '\u0645', '\u0645']), ('\ufdc4',
- &['\u0639', '\u062c', '\u0645']), ('\ufdc5', &['\u0635', '\u0645', '\u0645']), ('\ufdc6',
- &['\u0633', '\u062e', '\u064a']), ('\ufdc7', &['\u0646', '\u062c', '\u064a']), ('\ufdf0',
- &['\u0635', '\u0644', '\u06d2']), ('\ufdf1', &['\u0642', '\u0644', '\u06d2']), ('\ufdf2',
- &['\u0627', '\u0644', '\u0644', '\u0647']), ('\ufdf3', &['\u0627', '\u0643', '\u0628',
- '\u0631']), ('\ufdf4', &['\u0645', '\u062d', '\u0645', '\u062f']), ('\ufdf5', &['\u0635',
- '\u0644', '\u0639', '\u0645']), ('\ufdf6', &['\u0631', '\u0633', '\u0648', '\u0644']),
- ('\ufdf7', &['\u0639', '\u0644', '\u064a', '\u0647']), ('\ufdf8', &['\u0648', '\u0633',
- '\u0644', '\u0645']), ('\ufdf9', &['\u0635', '\u0644', '\u0649']), ('\ufdfa', &['\u0635',
- '\u0644', '\u0649', '\x20', '\u0627', '\u0644', '\u0644', '\u0647', '\x20', '\u0639',
- '\u0644', '\u064a', '\u0647', '\x20', '\u0648', '\u0633', '\u0644', '\u0645']), ('\ufdfb',
- &['\u062c', '\u0644', '\x20', '\u062c', '\u0644', '\u0627', '\u0644', '\u0647']), ('\ufdfc',
- &['\u0631', '\u06cc', '\u0627', '\u0644']), ('\ufe10', &['\x2c']), ('\ufe11', &['\u3001']),
- ('\ufe12', &['\u3002']), ('\ufe13', &['\x3a']), ('\ufe14', &['\x3b']), ('\ufe15',
- &['\x21']), ('\ufe16', &['\x3f']), ('\ufe17', &['\u3016']), ('\ufe18', &['\u3017']),
- ('\ufe19', &['\u2026']), ('\ufe30', &['\u2025']), ('\ufe31', &['\u2014']), ('\ufe32',
- &['\u2013']), ('\ufe33', &['\x5f']), ('\ufe34', &['\x5f']), ('\ufe35', &['\x28']),
- ('\ufe36', &['\x29']), ('\ufe37', &['\x7b']), ('\ufe38', &['\x7d']), ('\ufe39',
- &['\u3014']), ('\ufe3a', &['\u3015']), ('\ufe3b', &['\u3010']), ('\ufe3c', &['\u3011']),
- ('\ufe3d', &['\u300a']), ('\ufe3e', &['\u300b']), ('\ufe3f', &['\u3008']), ('\ufe40',
- &['\u3009']), ('\ufe41', &['\u300c']), ('\ufe42', &['\u300d']), ('\ufe43', &['\u300e']),
- ('\ufe44', &['\u300f']), ('\ufe47', &['\x5b']), ('\ufe48', &['\x5d']), ('\ufe49',
- &['\u203e']), ('\ufe4a', &['\u203e']), ('\ufe4b', &['\u203e']), ('\ufe4c', &['\u203e']),
- ('\ufe4d', &['\x5f']), ('\ufe4e', &['\x5f']), ('\ufe4f', &['\x5f']), ('\ufe50', &['\x2c']),
- ('\ufe51', &['\u3001']), ('\ufe52', &['\x2e']), ('\ufe54', &['\x3b']), ('\ufe55',
- &['\x3a']), ('\ufe56', &['\x3f']), ('\ufe57', &['\x21']), ('\ufe58', &['\u2014']),
- ('\ufe59', &['\x28']), ('\ufe5a', &['\x29']), ('\ufe5b', &['\x7b']), ('\ufe5c', &['\x7d']),
- ('\ufe5d', &['\u3014']), ('\ufe5e', &['\u3015']), ('\ufe5f', &['\x23']), ('\ufe60',
- &['\x26']), ('\ufe61', &['\x2a']), ('\ufe62', &['\x2b']), ('\ufe63', &['\x2d']), ('\ufe64',
- &['\x3c']), ('\ufe65', &['\x3e']), ('\ufe66', &['\x3d']), ('\ufe68', &['\x5c']), ('\ufe69',
- &['\x24']), ('\ufe6a', &['\x25']), ('\ufe6b', &['\x40']), ('\ufe70', &['\x20', '\u064b']),
- ('\ufe71', &['\u0640', '\u064b']), ('\ufe72', &['\x20', '\u064c']), ('\ufe74', &['\x20',
- '\u064d']), ('\ufe76', &['\x20', '\u064e']), ('\ufe77', &['\u0640', '\u064e']), ('\ufe78',
- &['\x20', '\u064f']), ('\ufe79', &['\u0640', '\u064f']), ('\ufe7a', &['\x20', '\u0650']),
- ('\ufe7b', &['\u0640', '\u0650']), ('\ufe7c', &['\x20', '\u0651']), ('\ufe7d', &['\u0640',
- '\u0651']), ('\ufe7e', &['\x20', '\u0652']), ('\ufe7f', &['\u0640', '\u0652']), ('\ufe80',
- &['\u0621']), ('\ufe81', &['\u0622']), ('\ufe82', &['\u0622']), ('\ufe83', &['\u0623']),
- ('\ufe84', &['\u0623']), ('\ufe85', &['\u0624']), ('\ufe86', &['\u0624']), ('\ufe87',
- &['\u0625']), ('\ufe88', &['\u0625']), ('\ufe89', &['\u0626']), ('\ufe8a', &['\u0626']),
- ('\ufe8b', &['\u0626']), ('\ufe8c', &['\u0626']), ('\ufe8d', &['\u0627']), ('\ufe8e',
- &['\u0627']), ('\ufe8f', &['\u0628']), ('\ufe90', &['\u0628']), ('\ufe91', &['\u0628']),
- ('\ufe92', &['\u0628']), ('\ufe93', &['\u0629']), ('\ufe94', &['\u0629']), ('\ufe95',
- &['\u062a']), ('\ufe96', &['\u062a']), ('\ufe97', &['\u062a']), ('\ufe98', &['\u062a']),
- ('\ufe99', &['\u062b']), ('\ufe9a', &['\u062b']), ('\ufe9b', &['\u062b']), ('\ufe9c',
- &['\u062b']), ('\ufe9d', &['\u062c']), ('\ufe9e', &['\u062c']), ('\ufe9f', &['\u062c']),
- ('\ufea0', &['\u062c']), ('\ufea1', &['\u062d']), ('\ufea2', &['\u062d']), ('\ufea3',
- &['\u062d']), ('\ufea4', &['\u062d']), ('\ufea5', &['\u062e']), ('\ufea6', &['\u062e']),
- ('\ufea7', &['\u062e']), ('\ufea8', &['\u062e']), ('\ufea9', &['\u062f']), ('\ufeaa',
- &['\u062f']), ('\ufeab', &['\u0630']), ('\ufeac', &['\u0630']), ('\ufead', &['\u0631']),
- ('\ufeae', &['\u0631']), ('\ufeaf', &['\u0632']), ('\ufeb0', &['\u0632']), ('\ufeb1',
- &['\u0633']), ('\ufeb2', &['\u0633']), ('\ufeb3', &['\u0633']), ('\ufeb4', &['\u0633']),
- ('\ufeb5', &['\u0634']), ('\ufeb6', &['\u0634']), ('\ufeb7', &['\u0634']), ('\ufeb8',
- &['\u0634']), ('\ufeb9', &['\u0635']), ('\ufeba', &['\u0635']), ('\ufebb', &['\u0635']),
- ('\ufebc', &['\u0635']), ('\ufebd', &['\u0636']), ('\ufebe', &['\u0636']), ('\ufebf',
- &['\u0636']), ('\ufec0', &['\u0636']), ('\ufec1', &['\u0637']), ('\ufec2', &['\u0637']),
- ('\ufec3', &['\u0637']), ('\ufec4', &['\u0637']), ('\ufec5', &['\u0638']), ('\ufec6',
- &['\u0638']), ('\ufec7', &['\u0638']), ('\ufec8', &['\u0638']), ('\ufec9', &['\u0639']),
- ('\ufeca', &['\u0639']), ('\ufecb', &['\u0639']), ('\ufecc', &['\u0639']), ('\ufecd',
- &['\u063a']), ('\ufece', &['\u063a']), ('\ufecf', &['\u063a']), ('\ufed0', &['\u063a']),
- ('\ufed1', &['\u0641']), ('\ufed2', &['\u0641']), ('\ufed3', &['\u0641']), ('\ufed4',
- &['\u0641']), ('\ufed5', &['\u0642']), ('\ufed6', &['\u0642']), ('\ufed7', &['\u0642']),
- ('\ufed8', &['\u0642']), ('\ufed9', &['\u0643']), ('\ufeda', &['\u0643']), ('\ufedb',
- &['\u0643']), ('\ufedc', &['\u0643']), ('\ufedd', &['\u0644']), ('\ufede', &['\u0644']),
- ('\ufedf', &['\u0644']), ('\ufee0', &['\u0644']), ('\ufee1', &['\u0645']), ('\ufee2',
- &['\u0645']), ('\ufee3', &['\u0645']), ('\ufee4', &['\u0645']), ('\ufee5', &['\u0646']),
- ('\ufee6', &['\u0646']), ('\ufee7', &['\u0646']), ('\ufee8', &['\u0646']), ('\ufee9',
- &['\u0647']), ('\ufeea', &['\u0647']), ('\ufeeb', &['\u0647']), ('\ufeec', &['\u0647']),
- ('\ufeed', &['\u0648']), ('\ufeee', &['\u0648']), ('\ufeef', &['\u0649']), ('\ufef0',
- &['\u0649']), ('\ufef1', &['\u064a']), ('\ufef2', &['\u064a']), ('\ufef3', &['\u064a']),
- ('\ufef4', &['\u064a']), ('\ufef5', &['\u0644', '\u0622']), ('\ufef6', &['\u0644',
- '\u0622']), ('\ufef7', &['\u0644', '\u0623']), ('\ufef8', &['\u0644', '\u0623']), ('\ufef9',
- &['\u0644', '\u0625']), ('\ufefa', &['\u0644', '\u0625']), ('\ufefb', &['\u0644',
- '\u0627']), ('\ufefc', &['\u0644', '\u0627']), ('\uff01', &['\x21']), ('\uff02', &['\x22']),
- ('\uff03', &['\x23']), ('\uff04', &['\x24']), ('\uff05', &['\x25']), ('\uff06', &['\x26']),
- ('\uff07', &['\x27']), ('\uff08', &['\x28']), ('\uff09', &['\x29']), ('\uff0a', &['\x2a']),
- ('\uff0b', &['\x2b']), ('\uff0c', &['\x2c']), ('\uff0d', &['\x2d']), ('\uff0e', &['\x2e']),
- ('\uff0f', &['\x2f']), ('\uff10', &['\x30']), ('\uff11', &['\x31']), ('\uff12', &['\x32']),
- ('\uff13', &['\x33']), ('\uff14', &['\x34']), ('\uff15', &['\x35']), ('\uff16', &['\x36']),
- ('\uff17', &['\x37']), ('\uff18', &['\x38']), ('\uff19', &['\x39']), ('\uff1a', &['\x3a']),
- ('\uff1b', &['\x3b']), ('\uff1c', &['\x3c']), ('\uff1d', &['\x3d']), ('\uff1e', &['\x3e']),
- ('\uff1f', &['\x3f']), ('\uff20', &['\x40']), ('\uff21', &['\x41']), ('\uff22', &['\x42']),
- ('\uff23', &['\x43']), ('\uff24', &['\x44']), ('\uff25', &['\x45']), ('\uff26', &['\x46']),
- ('\uff27', &['\x47']), ('\uff28', &['\x48']), ('\uff29', &['\x49']), ('\uff2a', &['\x4a']),
- ('\uff2b', &['\x4b']), ('\uff2c', &['\x4c']), ('\uff2d', &['\x4d']), ('\uff2e', &['\x4e']),
- ('\uff2f', &['\x4f']), ('\uff30', &['\x50']), ('\uff31', &['\x51']), ('\uff32', &['\x52']),
- ('\uff33', &['\x53']), ('\uff34', &['\x54']), ('\uff35', &['\x55']), ('\uff36', &['\x56']),
- ('\uff37', &['\x57']), ('\uff38', &['\x58']), ('\uff39', &['\x59']), ('\uff3a', &['\x5a']),
- ('\uff3b', &['\x5b']), ('\uff3c', &['\x5c']), ('\uff3d', &['\x5d']), ('\uff3e', &['\x5e']),
- ('\uff3f', &['\x5f']), ('\uff40', &['\x60']), ('\uff41', &['\x61']), ('\uff42', &['\x62']),
- ('\uff43', &['\x63']), ('\uff44', &['\x64']), ('\uff45', &['\x65']), ('\uff46', &['\x66']),
- ('\uff47', &['\x67']), ('\uff48', &['\x68']), ('\uff49', &['\x69']), ('\uff4a', &['\x6a']),
- ('\uff4b', &['\x6b']), ('\uff4c', &['\x6c']), ('\uff4d', &['\x6d']), ('\uff4e', &['\x6e']),
- ('\uff4f', &['\x6f']), ('\uff50', &['\x70']), ('\uff51', &['\x71']), ('\uff52', &['\x72']),
- ('\uff53', &['\x73']), ('\uff54', &['\x74']), ('\uff55', &['\x75']), ('\uff56', &['\x76']),
- ('\uff57', &['\x77']), ('\uff58', &['\x78']), ('\uff59', &['\x79']), ('\uff5a', &['\x7a']),
- ('\uff5b', &['\x7b']), ('\uff5c', &['\x7c']), ('\uff5d', &['\x7d']), ('\uff5e', &['\x7e']),
- ('\uff5f', &['\u2985']), ('\uff60', &['\u2986']), ('\uff61', &['\u3002']), ('\uff62',
- &['\u300c']), ('\uff63', &['\u300d']), ('\uff64', &['\u3001']), ('\uff65', &['\u30fb']),
- ('\uff66', &['\u30f2']), ('\uff67', &['\u30a1']), ('\uff68', &['\u30a3']), ('\uff69',
- &['\u30a5']), ('\uff6a', &['\u30a7']), ('\uff6b', &['\u30a9']), ('\uff6c', &['\u30e3']),
- ('\uff6d', &['\u30e5']), ('\uff6e', &['\u30e7']), ('\uff6f', &['\u30c3']), ('\uff70',
- &['\u30fc']), ('\uff71', &['\u30a2']), ('\uff72', &['\u30a4']), ('\uff73', &['\u30a6']),
- ('\uff74', &['\u30a8']), ('\uff75', &['\u30aa']), ('\uff76', &['\u30ab']), ('\uff77',
- &['\u30ad']), ('\uff78', &['\u30af']), ('\uff79', &['\u30b1']), ('\uff7a', &['\u30b3']),
- ('\uff7b', &['\u30b5']), ('\uff7c', &['\u30b7']), ('\uff7d', &['\u30b9']), ('\uff7e',
- &['\u30bb']), ('\uff7f', &['\u30bd']), ('\uff80', &['\u30bf']), ('\uff81', &['\u30c1']),
- ('\uff82', &['\u30c4']), ('\uff83', &['\u30c6']), ('\uff84', &['\u30c8']), ('\uff85',
- &['\u30ca']), ('\uff86', &['\u30cb']), ('\uff87', &['\u30cc']), ('\uff88', &['\u30cd']),
- ('\uff89', &['\u30ce']), ('\uff8a', &['\u30cf']), ('\uff8b', &['\u30d2']), ('\uff8c',
- &['\u30d5']), ('\uff8d', &['\u30d8']), ('\uff8e', &['\u30db']), ('\uff8f', &['\u30de']),
- ('\uff90', &['\u30df']), ('\uff91', &['\u30e0']), ('\uff92', &['\u30e1']), ('\uff93',
- &['\u30e2']), ('\uff94', &['\u30e4']), ('\uff95', &['\u30e6']), ('\uff96', &['\u30e8']),
- ('\uff97', &['\u30e9']), ('\uff98', &['\u30ea']), ('\uff99', &['\u30eb']), ('\uff9a',
- &['\u30ec']), ('\uff9b', &['\u30ed']), ('\uff9c', &['\u30ef']), ('\uff9d', &['\u30f3']),
- ('\uff9e', &['\u3099']), ('\uff9f', &['\u309a']), ('\uffa0', &['\u3164']), ('\uffa1',
- &['\u3131']), ('\uffa2', &['\u3132']), ('\uffa3', &['\u3133']), ('\uffa4', &['\u3134']),
- ('\uffa5', &['\u3135']), ('\uffa6', &['\u3136']), ('\uffa7', &['\u3137']), ('\uffa8',
- &['\u3138']), ('\uffa9', &['\u3139']), ('\uffaa', &['\u313a']), ('\uffab', &['\u313b']),
- ('\uffac', &['\u313c']), ('\uffad', &['\u313d']), ('\uffae', &['\u313e']), ('\uffaf',
- &['\u313f']), ('\uffb0', &['\u3140']), ('\uffb1', &['\u3141']), ('\uffb2', &['\u3142']),
- ('\uffb3', &['\u3143']), ('\uffb4', &['\u3144']), ('\uffb5', &['\u3145']), ('\uffb6',
- &['\u3146']), ('\uffb7', &['\u3147']), ('\uffb8', &['\u3148']), ('\uffb9', &['\u3149']),
- ('\uffba', &['\u314a']), ('\uffbb', &['\u314b']), ('\uffbc', &['\u314c']), ('\uffbd',
- &['\u314d']), ('\uffbe', &['\u314e']), ('\uffc2', &['\u314f']), ('\uffc3', &['\u3150']),
- ('\uffc4', &['\u3151']), ('\uffc5', &['\u3152']), ('\uffc6', &['\u3153']), ('\uffc7',
- &['\u3154']), ('\uffca', &['\u3155']), ('\uffcb', &['\u3156']), ('\uffcc', &['\u3157']),
- ('\uffcd', &['\u3158']), ('\uffce', &['\u3159']), ('\uffcf', &['\u315a']), ('\uffd2',
- &['\u315b']), ('\uffd3', &['\u315c']), ('\uffd4', &['\u315d']), ('\uffd5', &['\u315e']),
- ('\uffd6', &['\u315f']), ('\uffd7', &['\u3160']), ('\uffda', &['\u3161']), ('\uffdb',
- &['\u3162']), ('\uffdc', &['\u3163']), ('\uffe0', &['\xa2']), ('\uffe1', &['\xa3']),
- ('\uffe2', &['\xac']), ('\uffe3', &['\xaf']), ('\uffe4', &['\xa6']), ('\uffe5', &['\xa5']),
- ('\uffe6', &['\u20a9']), ('\uffe8', &['\u2502']), ('\uffe9', &['\u2190']), ('\uffea',
- &['\u2191']), ('\uffeb', &['\u2192']), ('\uffec', &['\u2193']), ('\uffed', &['\u25a0']),
- ('\uffee', &['\u25cb']), ('\U0001d400', &['\x41']), ('\U0001d401', &['\x42']),
- ('\U0001d402', &['\x43']), ('\U0001d403', &['\x44']), ('\U0001d404', &['\x45']),
- ('\U0001d405', &['\x46']), ('\U0001d406', &['\x47']), ('\U0001d407', &['\x48']),
- ('\U0001d408', &['\x49']), ('\U0001d409', &['\x4a']), ('\U0001d40a', &['\x4b']),
- ('\U0001d40b', &['\x4c']), ('\U0001d40c', &['\x4d']), ('\U0001d40d', &['\x4e']),
- ('\U0001d40e', &['\x4f']), ('\U0001d40f', &['\x50']), ('\U0001d410', &['\x51']),
- ('\U0001d411', &['\x52']), ('\U0001d412', &['\x53']), ('\U0001d413', &['\x54']),
- ('\U0001d414', &['\x55']), ('\U0001d415', &['\x56']), ('\U0001d416', &['\x57']),
- ('\U0001d417', &['\x58']), ('\U0001d418', &['\x59']), ('\U0001d419', &['\x5a']),
- ('\U0001d41a', &['\x61']), ('\U0001d41b', &['\x62']), ('\U0001d41c', &['\x63']),
- ('\U0001d41d', &['\x64']), ('\U0001d41e', &['\x65']), ('\U0001d41f', &['\x66']),
- ('\U0001d420', &['\x67']), ('\U0001d421', &['\x68']), ('\U0001d422', &['\x69']),
- ('\U0001d423', &['\x6a']), ('\U0001d424', &['\x6b']), ('\U0001d425', &['\x6c']),
- ('\U0001d426', &['\x6d']), ('\U0001d427', &['\x6e']), ('\U0001d428', &['\x6f']),
- ('\U0001d429', &['\x70']), ('\U0001d42a', &['\x71']), ('\U0001d42b', &['\x72']),
- ('\U0001d42c', &['\x73']), ('\U0001d42d', &['\x74']), ('\U0001d42e', &['\x75']),
- ('\U0001d42f', &['\x76']), ('\U0001d430', &['\x77']), ('\U0001d431', &['\x78']),
- ('\U0001d432', &['\x79']), ('\U0001d433', &['\x7a']), ('\U0001d434', &['\x41']),
- ('\U0001d435', &['\x42']), ('\U0001d436', &['\x43']), ('\U0001d437', &['\x44']),
- ('\U0001d438', &['\x45']), ('\U0001d439', &['\x46']), ('\U0001d43a', &['\x47']),
- ('\U0001d43b', &['\x48']), ('\U0001d43c', &['\x49']), ('\U0001d43d', &['\x4a']),
- ('\U0001d43e', &['\x4b']), ('\U0001d43f', &['\x4c']), ('\U0001d440', &['\x4d']),
- ('\U0001d441', &['\x4e']), ('\U0001d442', &['\x4f']), ('\U0001d443', &['\x50']),
- ('\U0001d444', &['\x51']), ('\U0001d445', &['\x52']), ('\U0001d446', &['\x53']),
- ('\U0001d447', &['\x54']), ('\U0001d448', &['\x55']), ('\U0001d449', &['\x56']),
- ('\U0001d44a', &['\x57']), ('\U0001d44b', &['\x58']), ('\U0001d44c', &['\x59']),
- ('\U0001d44d', &['\x5a']), ('\U0001d44e', &['\x61']), ('\U0001d44f', &['\x62']),
- ('\U0001d450', &['\x63']), ('\U0001d451', &['\x64']), ('\U0001d452', &['\x65']),
- ('\U0001d453', &['\x66']), ('\U0001d454', &['\x67']), ('\U0001d456', &['\x69']),
- ('\U0001d457', &['\x6a']), ('\U0001d458', &['\x6b']), ('\U0001d459', &['\x6c']),
- ('\U0001d45a', &['\x6d']), ('\U0001d45b', &['\x6e']), ('\U0001d45c', &['\x6f']),
- ('\U0001d45d', &['\x70']), ('\U0001d45e', &['\x71']), ('\U0001d45f', &['\x72']),
- ('\U0001d460', &['\x73']), ('\U0001d461', &['\x74']), ('\U0001d462', &['\x75']),
- ('\U0001d463', &['\x76']), ('\U0001d464', &['\x77']), ('\U0001d465', &['\x78']),
- ('\U0001d466', &['\x79']), ('\U0001d467', &['\x7a']), ('\U0001d468', &['\x41']),
- ('\U0001d469', &['\x42']), ('\U0001d46a', &['\x43']), ('\U0001d46b', &['\x44']),
- ('\U0001d46c', &['\x45']), ('\U0001d46d', &['\x46']), ('\U0001d46e', &['\x47']),
- ('\U0001d46f', &['\x48']), ('\U0001d470', &['\x49']), ('\U0001d471', &['\x4a']),
- ('\U0001d472', &['\x4b']), ('\U0001d473', &['\x4c']), ('\U0001d474', &['\x4d']),
- ('\U0001d475', &['\x4e']), ('\U0001d476', &['\x4f']), ('\U0001d477', &['\x50']),
- ('\U0001d478', &['\x51']), ('\U0001d479', &['\x52']), ('\U0001d47a', &['\x53']),
- ('\U0001d47b', &['\x54']), ('\U0001d47c', &['\x55']), ('\U0001d47d', &['\x56']),
- ('\U0001d47e', &['\x57']), ('\U0001d47f', &['\x58']), ('\U0001d480', &['\x59']),
- ('\U0001d481', &['\x5a']), ('\U0001d482', &['\x61']), ('\U0001d483', &['\x62']),
- ('\U0001d484', &['\x63']), ('\U0001d485', &['\x64']), ('\U0001d486', &['\x65']),
- ('\U0001d487', &['\x66']), ('\U0001d488', &['\x67']), ('\U0001d489', &['\x68']),
- ('\U0001d48a', &['\x69']), ('\U0001d48b', &['\x6a']), ('\U0001d48c', &['\x6b']),
- ('\U0001d48d', &['\x6c']), ('\U0001d48e', &['\x6d']), ('\U0001d48f', &['\x6e']),
- ('\U0001d490', &['\x6f']), ('\U0001d491', &['\x70']), ('\U0001d492', &['\x71']),
- ('\U0001d493', &['\x72']), ('\U0001d494', &['\x73']), ('\U0001d495', &['\x74']),
- ('\U0001d496', &['\x75']), ('\U0001d497', &['\x76']), ('\U0001d498', &['\x77']),
- ('\U0001d499', &['\x78']), ('\U0001d49a', &['\x79']), ('\U0001d49b', &['\x7a']),
- ('\U0001d49c', &['\x41']), ('\U0001d49e', &['\x43']), ('\U0001d49f', &['\x44']),
- ('\U0001d4a2', &['\x47']), ('\U0001d4a5', &['\x4a']), ('\U0001d4a6', &['\x4b']),
- ('\U0001d4a9', &['\x4e']), ('\U0001d4aa', &['\x4f']), ('\U0001d4ab', &['\x50']),
- ('\U0001d4ac', &['\x51']), ('\U0001d4ae', &['\x53']), ('\U0001d4af', &['\x54']),
- ('\U0001d4b0', &['\x55']), ('\U0001d4b1', &['\x56']), ('\U0001d4b2', &['\x57']),
- ('\U0001d4b3', &['\x58']), ('\U0001d4b4', &['\x59']), ('\U0001d4b5', &['\x5a']),
- ('\U0001d4b6', &['\x61']), ('\U0001d4b7', &['\x62']), ('\U0001d4b8', &['\x63']),
- ('\U0001d4b9', &['\x64']), ('\U0001d4bb', &['\x66']), ('\U0001d4bd', &['\x68']),
- ('\U0001d4be', &['\x69']), ('\U0001d4bf', &['\x6a']), ('\U0001d4c0', &['\x6b']),
- ('\U0001d4c1', &['\x6c']), ('\U0001d4c2', &['\x6d']), ('\U0001d4c3', &['\x6e']),
- ('\U0001d4c5', &['\x70']), ('\U0001d4c6', &['\x71']), ('\U0001d4c7', &['\x72']),
- ('\U0001d4c8', &['\x73']), ('\U0001d4c9', &['\x74']), ('\U0001d4ca', &['\x75']),
- ('\U0001d4cb', &['\x76']), ('\U0001d4cc', &['\x77']), ('\U0001d4cd', &['\x78']),
- ('\U0001d4ce', &['\x79']), ('\U0001d4cf', &['\x7a']), ('\U0001d4d0', &['\x41']),
- ('\U0001d4d1', &['\x42']), ('\U0001d4d2', &['\x43']), ('\U0001d4d3', &['\x44']),
- ('\U0001d4d4', &['\x45']), ('\U0001d4d5', &['\x46']), ('\U0001d4d6', &['\x47']),
- ('\U0001d4d7', &['\x48']), ('\U0001d4d8', &['\x49']), ('\U0001d4d9', &['\x4a']),
- ('\U0001d4da', &['\x4b']), ('\U0001d4db', &['\x4c']), ('\U0001d4dc', &['\x4d']),
- ('\U0001d4dd', &['\x4e']), ('\U0001d4de', &['\x4f']), ('\U0001d4df', &['\x50']),
- ('\U0001d4e0', &['\x51']), ('\U0001d4e1', &['\x52']), ('\U0001d4e2', &['\x53']),
- ('\U0001d4e3', &['\x54']), ('\U0001d4e4', &['\x55']), ('\U0001d4e5', &['\x56']),
- ('\U0001d4e6', &['\x57']), ('\U0001d4e7', &['\x58']), ('\U0001d4e8', &['\x59']),
- ('\U0001d4e9', &['\x5a']), ('\U0001d4ea', &['\x61']), ('\U0001d4eb', &['\x62']),
- ('\U0001d4ec', &['\x63']), ('\U0001d4ed', &['\x64']), ('\U0001d4ee', &['\x65']),
- ('\U0001d4ef', &['\x66']), ('\U0001d4f0', &['\x67']), ('\U0001d4f1', &['\x68']),
- ('\U0001d4f2', &['\x69']), ('\U0001d4f3', &['\x6a']), ('\U0001d4f4', &['\x6b']),
- ('\U0001d4f5', &['\x6c']), ('\U0001d4f6', &['\x6d']), ('\U0001d4f7', &['\x6e']),
- ('\U0001d4f8', &['\x6f']), ('\U0001d4f9', &['\x70']), ('\U0001d4fa', &['\x71']),
- ('\U0001d4fb', &['\x72']), ('\U0001d4fc', &['\x73']), ('\U0001d4fd', &['\x74']),
- ('\U0001d4fe', &['\x75']), ('\U0001d4ff', &['\x76']), ('\U0001d500', &['\x77']),
- ('\U0001d501', &['\x78']), ('\U0001d502', &['\x79']), ('\U0001d503', &['\x7a']),
- ('\U0001d504', &['\x41']), ('\U0001d505', &['\x42']), ('\U0001d507', &['\x44']),
- ('\U0001d508', &['\x45']), ('\U0001d509', &['\x46']), ('\U0001d50a', &['\x47']),
- ('\U0001d50d', &['\x4a']), ('\U0001d50e', &['\x4b']), ('\U0001d50f', &['\x4c']),
- ('\U0001d510', &['\x4d']), ('\U0001d511', &['\x4e']), ('\U0001d512', &['\x4f']),
- ('\U0001d513', &['\x50']), ('\U0001d514', &['\x51']), ('\U0001d516', &['\x53']),
- ('\U0001d517', &['\x54']), ('\U0001d518', &['\x55']), ('\U0001d519', &['\x56']),
- ('\U0001d51a', &['\x57']), ('\U0001d51b', &['\x58']), ('\U0001d51c', &['\x59']),
- ('\U0001d51e', &['\x61']), ('\U0001d51f', &['\x62']), ('\U0001d520', &['\x63']),
- ('\U0001d521', &['\x64']), ('\U0001d522', &['\x65']), ('\U0001d523', &['\x66']),
- ('\U0001d524', &['\x67']), ('\U0001d525', &['\x68']), ('\U0001d526', &['\x69']),
- ('\U0001d527', &['\x6a']), ('\U0001d528', &['\x6b']), ('\U0001d529', &['\x6c']),
- ('\U0001d52a', &['\x6d']), ('\U0001d52b', &['\x6e']), ('\U0001d52c', &['\x6f']),
- ('\U0001d52d', &['\x70']), ('\U0001d52e', &['\x71']), ('\U0001d52f', &['\x72']),
- ('\U0001d530', &['\x73']), ('\U0001d531', &['\x74']), ('\U0001d532', &['\x75']),
- ('\U0001d533', &['\x76']), ('\U0001d534', &['\x77']), ('\U0001d535', &['\x78']),
- ('\U0001d536', &['\x79']), ('\U0001d537', &['\x7a']), ('\U0001d538', &['\x41']),
- ('\U0001d539', &['\x42']), ('\U0001d53b', &['\x44']), ('\U0001d53c', &['\x45']),
- ('\U0001d53d', &['\x46']), ('\U0001d53e', &['\x47']), ('\U0001d540', &['\x49']),
- ('\U0001d541', &['\x4a']), ('\U0001d542', &['\x4b']), ('\U0001d543', &['\x4c']),
- ('\U0001d544', &['\x4d']), ('\U0001d546', &['\x4f']), ('\U0001d54a', &['\x53']),
- ('\U0001d54b', &['\x54']), ('\U0001d54c', &['\x55']), ('\U0001d54d', &['\x56']),
- ('\U0001d54e', &['\x57']), ('\U0001d54f', &['\x58']), ('\U0001d550', &['\x59']),
- ('\U0001d552', &['\x61']), ('\U0001d553', &['\x62']), ('\U0001d554', &['\x63']),
- ('\U0001d555', &['\x64']), ('\U0001d556', &['\x65']), ('\U0001d557', &['\x66']),
- ('\U0001d558', &['\x67']), ('\U0001d559', &['\x68']), ('\U0001d55a', &['\x69']),
- ('\U0001d55b', &['\x6a']), ('\U0001d55c', &['\x6b']), ('\U0001d55d', &['\x6c']),
- ('\U0001d55e', &['\x6d']), ('\U0001d55f', &['\x6e']), ('\U0001d560', &['\x6f']),
- ('\U0001d561', &['\x70']), ('\U0001d562', &['\x71']), ('\U0001d563', &['\x72']),
- ('\U0001d564', &['\x73']), ('\U0001d565', &['\x74']), ('\U0001d566', &['\x75']),
- ('\U0001d567', &['\x76']), ('\U0001d568', &['\x77']), ('\U0001d569', &['\x78']),
- ('\U0001d56a', &['\x79']), ('\U0001d56b', &['\x7a']), ('\U0001d56c', &['\x41']),
- ('\U0001d56d', &['\x42']), ('\U0001d56e', &['\x43']), ('\U0001d56f', &['\x44']),
- ('\U0001d570', &['\x45']), ('\U0001d571', &['\x46']), ('\U0001d572', &['\x47']),
- ('\U0001d573', &['\x48']), ('\U0001d574', &['\x49']), ('\U0001d575', &['\x4a']),
- ('\U0001d576', &['\x4b']), ('\U0001d577', &['\x4c']), ('\U0001d578', &['\x4d']),
- ('\U0001d579', &['\x4e']), ('\U0001d57a', &['\x4f']), ('\U0001d57b', &['\x50']),
- ('\U0001d57c', &['\x51']), ('\U0001d57d', &['\x52']), ('\U0001d57e', &['\x53']),
- ('\U0001d57f', &['\x54']), ('\U0001d580', &['\x55']), ('\U0001d581', &['\x56']),
- ('\U0001d582', &['\x57']), ('\U0001d583', &['\x58']), ('\U0001d584', &['\x59']),
- ('\U0001d585', &['\x5a']), ('\U0001d586', &['\x61']), ('\U0001d587', &['\x62']),
- ('\U0001d588', &['\x63']), ('\U0001d589', &['\x64']), ('\U0001d58a', &['\x65']),
- ('\U0001d58b', &['\x66']), ('\U0001d58c', &['\x67']), ('\U0001d58d', &['\x68']),
- ('\U0001d58e', &['\x69']), ('\U0001d58f', &['\x6a']), ('\U0001d590', &['\x6b']),
- ('\U0001d591', &['\x6c']), ('\U0001d592', &['\x6d']), ('\U0001d593', &['\x6e']),
- ('\U0001d594', &['\x6f']), ('\U0001d595', &['\x70']), ('\U0001d596', &['\x71']),
- ('\U0001d597', &['\x72']), ('\U0001d598', &['\x73']), ('\U0001d599', &['\x74']),
- ('\U0001d59a', &['\x75']), ('\U0001d59b', &['\x76']), ('\U0001d59c', &['\x77']),
- ('\U0001d59d', &['\x78']), ('\U0001d59e', &['\x79']), ('\U0001d59f', &['\x7a']),
- ('\U0001d5a0', &['\x41']), ('\U0001d5a1', &['\x42']), ('\U0001d5a2', &['\x43']),
- ('\U0001d5a3', &['\x44']), ('\U0001d5a4', &['\x45']), ('\U0001d5a5', &['\x46']),
- ('\U0001d5a6', &['\x47']), ('\U0001d5a7', &['\x48']), ('\U0001d5a8', &['\x49']),
- ('\U0001d5a9', &['\x4a']), ('\U0001d5aa', &['\x4b']), ('\U0001d5ab', &['\x4c']),
- ('\U0001d5ac', &['\x4d']), ('\U0001d5ad', &['\x4e']), ('\U0001d5ae', &['\x4f']),
- ('\U0001d5af', &['\x50']), ('\U0001d5b0', &['\x51']), ('\U0001d5b1', &['\x52']),
- ('\U0001d5b2', &['\x53']), ('\U0001d5b3', &['\x54']), ('\U0001d5b4', &['\x55']),
- ('\U0001d5b5', &['\x56']), ('\U0001d5b6', &['\x57']), ('\U0001d5b7', &['\x58']),
- ('\U0001d5b8', &['\x59']), ('\U0001d5b9', &['\x5a']), ('\U0001d5ba', &['\x61']),
- ('\U0001d5bb', &['\x62']), ('\U0001d5bc', &['\x63']), ('\U0001d5bd', &['\x64']),
- ('\U0001d5be', &['\x65']), ('\U0001d5bf', &['\x66']), ('\U0001d5c0', &['\x67']),
- ('\U0001d5c1', &['\x68']), ('\U0001d5c2', &['\x69']), ('\U0001d5c3', &['\x6a']),
- ('\U0001d5c4', &['\x6b']), ('\U0001d5c5', &['\x6c']), ('\U0001d5c6', &['\x6d']),
- ('\U0001d5c7', &['\x6e']), ('\U0001d5c8', &['\x6f']), ('\U0001d5c9', &['\x70']),
- ('\U0001d5ca', &['\x71']), ('\U0001d5cb', &['\x72']), ('\U0001d5cc', &['\x73']),
- ('\U0001d5cd', &['\x74']), ('\U0001d5ce', &['\x75']), ('\U0001d5cf', &['\x76']),
- ('\U0001d5d0', &['\x77']), ('\U0001d5d1', &['\x78']), ('\U0001d5d2', &['\x79']),
- ('\U0001d5d3', &['\x7a']), ('\U0001d5d4', &['\x41']), ('\U0001d5d5', &['\x42']),
- ('\U0001d5d6', &['\x43']), ('\U0001d5d7', &['\x44']), ('\U0001d5d8', &['\x45']),
- ('\U0001d5d9', &['\x46']), ('\U0001d5da', &['\x47']), ('\U0001d5db', &['\x48']),
- ('\U0001d5dc', &['\x49']), ('\U0001d5dd', &['\x4a']), ('\U0001d5de', &['\x4b']),
- ('\U0001d5df', &['\x4c']), ('\U0001d5e0', &['\x4d']), ('\U0001d5e1', &['\x4e']),
- ('\U0001d5e2', &['\x4f']), ('\U0001d5e3', &['\x50']), ('\U0001d5e4', &['\x51']),
- ('\U0001d5e5', &['\x52']), ('\U0001d5e6', &['\x53']), ('\U0001d5e7', &['\x54']),
- ('\U0001d5e8', &['\x55']), ('\U0001d5e9', &['\x56']), ('\U0001d5ea', &['\x57']),
- ('\U0001d5eb', &['\x58']), ('\U0001d5ec', &['\x59']), ('\U0001d5ed', &['\x5a']),
- ('\U0001d5ee', &['\x61']), ('\U0001d5ef', &['\x62']), ('\U0001d5f0', &['\x63']),
- ('\U0001d5f1', &['\x64']), ('\U0001d5f2', &['\x65']), ('\U0001d5f3', &['\x66']),
- ('\U0001d5f4', &['\x67']), ('\U0001d5f5', &['\x68']), ('\U0001d5f6', &['\x69']),
- ('\U0001d5f7', &['\x6a']), ('\U0001d5f8', &['\x6b']), ('\U0001d5f9', &['\x6c']),
- ('\U0001d5fa', &['\x6d']), ('\U0001d5fb', &['\x6e']), ('\U0001d5fc', &['\x6f']),
- ('\U0001d5fd', &['\x70']), ('\U0001d5fe', &['\x71']), ('\U0001d5ff', &['\x72']),
- ('\U0001d600', &['\x73']), ('\U0001d601', &['\x74']), ('\U0001d602', &['\x75']),
- ('\U0001d603', &['\x76']), ('\U0001d604', &['\x77']), ('\U0001d605', &['\x78']),
- ('\U0001d606', &['\x79']), ('\U0001d607', &['\x7a']), ('\U0001d608', &['\x41']),
- ('\U0001d609', &['\x42']), ('\U0001d60a', &['\x43']), ('\U0001d60b', &['\x44']),
- ('\U0001d60c', &['\x45']), ('\U0001d60d', &['\x46']), ('\U0001d60e', &['\x47']),
- ('\U0001d60f', &['\x48']), ('\U0001d610', &['\x49']), ('\U0001d611', &['\x4a']),
- ('\U0001d612', &['\x4b']), ('\U0001d613', &['\x4c']), ('\U0001d614', &['\x4d']),
- ('\U0001d615', &['\x4e']), ('\U0001d616', &['\x4f']), ('\U0001d617', &['\x50']),
- ('\U0001d618', &['\x51']), ('\U0001d619', &['\x52']), ('\U0001d61a', &['\x53']),
- ('\U0001d61b', &['\x54']), ('\U0001d61c', &['\x55']), ('\U0001d61d', &['\x56']),
- ('\U0001d61e', &['\x57']), ('\U0001d61f', &['\x58']), ('\U0001d620', &['\x59']),
- ('\U0001d621', &['\x5a']), ('\U0001d622', &['\x61']), ('\U0001d623', &['\x62']),
- ('\U0001d624', &['\x63']), ('\U0001d625', &['\x64']), ('\U0001d626', &['\x65']),
- ('\U0001d627', &['\x66']), ('\U0001d628', &['\x67']), ('\U0001d629', &['\x68']),
- ('\U0001d62a', &['\x69']), ('\U0001d62b', &['\x6a']), ('\U0001d62c', &['\x6b']),
- ('\U0001d62d', &['\x6c']), ('\U0001d62e', &['\x6d']), ('\U0001d62f', &['\x6e']),
- ('\U0001d630', &['\x6f']), ('\U0001d631', &['\x70']), ('\U0001d632', &['\x71']),
- ('\U0001d633', &['\x72']), ('\U0001d634', &['\x73']), ('\U0001d635', &['\x74']),
- ('\U0001d636', &['\x75']), ('\U0001d637', &['\x76']), ('\U0001d638', &['\x77']),
- ('\U0001d639', &['\x78']), ('\U0001d63a', &['\x79']), ('\U0001d63b', &['\x7a']),
- ('\U0001d63c', &['\x41']), ('\U0001d63d', &['\x42']), ('\U0001d63e', &['\x43']),
- ('\U0001d63f', &['\x44']), ('\U0001d640', &['\x45']), ('\U0001d641', &['\x46']),
- ('\U0001d642', &['\x47']), ('\U0001d643', &['\x48']), ('\U0001d644', &['\x49']),
- ('\U0001d645', &['\x4a']), ('\U0001d646', &['\x4b']), ('\U0001d647', &['\x4c']),
- ('\U0001d648', &['\x4d']), ('\U0001d649', &['\x4e']), ('\U0001d64a', &['\x4f']),
- ('\U0001d64b', &['\x50']), ('\U0001d64c', &['\x51']), ('\U0001d64d', &['\x52']),
- ('\U0001d64e', &['\x53']), ('\U0001d64f', &['\x54']), ('\U0001d650', &['\x55']),
- ('\U0001d651', &['\x56']), ('\U0001d652', &['\x57']), ('\U0001d653', &['\x58']),
- ('\U0001d654', &['\x59']), ('\U0001d655', &['\x5a']), ('\U0001d656', &['\x61']),
- ('\U0001d657', &['\x62']), ('\U0001d658', &['\x63']), ('\U0001d659', &['\x64']),
- ('\U0001d65a', &['\x65']), ('\U0001d65b', &['\x66']), ('\U0001d65c', &['\x67']),
- ('\U0001d65d', &['\x68']), ('\U0001d65e', &['\x69']), ('\U0001d65f', &['\x6a']),
- ('\U0001d660', &['\x6b']), ('\U0001d661', &['\x6c']), ('\U0001d662', &['\x6d']),
- ('\U0001d663', &['\x6e']), ('\U0001d664', &['\x6f']), ('\U0001d665', &['\x70']),
- ('\U0001d666', &['\x71']), ('\U0001d667', &['\x72']), ('\U0001d668', &['\x73']),
- ('\U0001d669', &['\x74']), ('\U0001d66a', &['\x75']), ('\U0001d66b', &['\x76']),
- ('\U0001d66c', &['\x77']), ('\U0001d66d', &['\x78']), ('\U0001d66e', &['\x79']),
- ('\U0001d66f', &['\x7a']), ('\U0001d670', &['\x41']), ('\U0001d671', &['\x42']),
- ('\U0001d672', &['\x43']), ('\U0001d673', &['\x44']), ('\U0001d674', &['\x45']),
- ('\U0001d675', &['\x46']), ('\U0001d676', &['\x47']), ('\U0001d677', &['\x48']),
- ('\U0001d678', &['\x49']), ('\U0001d679', &['\x4a']), ('\U0001d67a', &['\x4b']),
- ('\U0001d67b', &['\x4c']), ('\U0001d67c', &['\x4d']), ('\U0001d67d', &['\x4e']),
- ('\U0001d67e', &['\x4f']), ('\U0001d67f', &['\x50']), ('\U0001d680', &['\x51']),
- ('\U0001d681', &['\x52']), ('\U0001d682', &['\x53']), ('\U0001d683', &['\x54']),
- ('\U0001d684', &['\x55']), ('\U0001d685', &['\x56']), ('\U0001d686', &['\x57']),
- ('\U0001d687', &['\x58']), ('\U0001d688', &['\x59']), ('\U0001d689', &['\x5a']),
- ('\U0001d68a', &['\x61']), ('\U0001d68b', &['\x62']), ('\U0001d68c', &['\x63']),
- ('\U0001d68d', &['\x64']), ('\U0001d68e', &['\x65']), ('\U0001d68f', &['\x66']),
- ('\U0001d690', &['\x67']), ('\U0001d691', &['\x68']), ('\U0001d692', &['\x69']),
- ('\U0001d693', &['\x6a']), ('\U0001d694', &['\x6b']), ('\U0001d695', &['\x6c']),
- ('\U0001d696', &['\x6d']), ('\U0001d697', &['\x6e']), ('\U0001d698', &['\x6f']),
- ('\U0001d699', &['\x70']), ('\U0001d69a', &['\x71']), ('\U0001d69b', &['\x72']),
- ('\U0001d69c', &['\x73']), ('\U0001d69d', &['\x74']), ('\U0001d69e', &['\x75']),
- ('\U0001d69f', &['\x76']), ('\U0001d6a0', &['\x77']), ('\U0001d6a1', &['\x78']),
- ('\U0001d6a2', &['\x79']), ('\U0001d6a3', &['\x7a']), ('\U0001d6a4', &['\u0131']),
- ('\U0001d6a5', &['\u0237']), ('\U0001d6a8', &['\u0391']), ('\U0001d6a9', &['\u0392']),
- ('\U0001d6aa', &['\u0393']), ('\U0001d6ab', &['\u0394']), ('\U0001d6ac', &['\u0395']),
- ('\U0001d6ad', &['\u0396']), ('\U0001d6ae', &['\u0397']), ('\U0001d6af', &['\u0398']),
- ('\U0001d6b0', &['\u0399']), ('\U0001d6b1', &['\u039a']), ('\U0001d6b2', &['\u039b']),
- ('\U0001d6b3', &['\u039c']), ('\U0001d6b4', &['\u039d']), ('\U0001d6b5', &['\u039e']),
- ('\U0001d6b6', &['\u039f']), ('\U0001d6b7', &['\u03a0']), ('\U0001d6b8', &['\u03a1']),
- ('\U0001d6b9', &['\u03f4']), ('\U0001d6ba', &['\u03a3']), ('\U0001d6bb', &['\u03a4']),
- ('\U0001d6bc', &['\u03a5']), ('\U0001d6bd', &['\u03a6']), ('\U0001d6be', &['\u03a7']),
- ('\U0001d6bf', &['\u03a8']), ('\U0001d6c0', &['\u03a9']), ('\U0001d6c1', &['\u2207']),
- ('\U0001d6c2', &['\u03b1']), ('\U0001d6c3', &['\u03b2']), ('\U0001d6c4', &['\u03b3']),
- ('\U0001d6c5', &['\u03b4']), ('\U0001d6c6', &['\u03b5']), ('\U0001d6c7', &['\u03b6']),
- ('\U0001d6c8', &['\u03b7']), ('\U0001d6c9', &['\u03b8']), ('\U0001d6ca', &['\u03b9']),
- ('\U0001d6cb', &['\u03ba']), ('\U0001d6cc', &['\u03bb']), ('\U0001d6cd', &['\u03bc']),
- ('\U0001d6ce', &['\u03bd']), ('\U0001d6cf', &['\u03be']), ('\U0001d6d0', &['\u03bf']),
- ('\U0001d6d1', &['\u03c0']), ('\U0001d6d2', &['\u03c1']), ('\U0001d6d3', &['\u03c2']),
- ('\U0001d6d4', &['\u03c3']), ('\U0001d6d5', &['\u03c4']), ('\U0001d6d6', &['\u03c5']),
- ('\U0001d6d7', &['\u03c6']), ('\U0001d6d8', &['\u03c7']), ('\U0001d6d9', &['\u03c8']),
- ('\U0001d6da', &['\u03c9']), ('\U0001d6db', &['\u2202']), ('\U0001d6dc', &['\u03f5']),
- ('\U0001d6dd', &['\u03d1']), ('\U0001d6de', &['\u03f0']), ('\U0001d6df', &['\u03d5']),
- ('\U0001d6e0', &['\u03f1']), ('\U0001d6e1', &['\u03d6']), ('\U0001d6e2', &['\u0391']),
- ('\U0001d6e3', &['\u0392']), ('\U0001d6e4', &['\u0393']), ('\U0001d6e5', &['\u0394']),
- ('\U0001d6e6', &['\u0395']), ('\U0001d6e7', &['\u0396']), ('\U0001d6e8', &['\u0397']),
- ('\U0001d6e9', &['\u0398']), ('\U0001d6ea', &['\u0399']), ('\U0001d6eb', &['\u039a']),
- ('\U0001d6ec', &['\u039b']), ('\U0001d6ed', &['\u039c']), ('\U0001d6ee', &['\u039d']),
- ('\U0001d6ef', &['\u039e']), ('\U0001d6f0', &['\u039f']), ('\U0001d6f1', &['\u03a0']),
- ('\U0001d6f2', &['\u03a1']), ('\U0001d6f3', &['\u03f4']), ('\U0001d6f4', &['\u03a3']),
- ('\U0001d6f5', &['\u03a4']), ('\U0001d6f6', &['\u03a5']), ('\U0001d6f7', &['\u03a6']),
- ('\U0001d6f8', &['\u03a7']), ('\U0001d6f9', &['\u03a8']), ('\U0001d6fa', &['\u03a9']),
- ('\U0001d6fb', &['\u2207']), ('\U0001d6fc', &['\u03b1']), ('\U0001d6fd', &['\u03b2']),
- ('\U0001d6fe', &['\u03b3']), ('\U0001d6ff', &['\u03b4']), ('\U0001d700', &['\u03b5']),
- ('\U0001d701', &['\u03b6']), ('\U0001d702', &['\u03b7']), ('\U0001d703', &['\u03b8']),
- ('\U0001d704', &['\u03b9']), ('\U0001d705', &['\u03ba']), ('\U0001d706', &['\u03bb']),
- ('\U0001d707', &['\u03bc']), ('\U0001d708', &['\u03bd']), ('\U0001d709', &['\u03be']),
- ('\U0001d70a', &['\u03bf']), ('\U0001d70b', &['\u03c0']), ('\U0001d70c', &['\u03c1']),
- ('\U0001d70d', &['\u03c2']), ('\U0001d70e', &['\u03c3']), ('\U0001d70f', &['\u03c4']),
- ('\U0001d710', &['\u03c5']), ('\U0001d711', &['\u03c6']), ('\U0001d712', &['\u03c7']),
- ('\U0001d713', &['\u03c8']), ('\U0001d714', &['\u03c9']), ('\U0001d715', &['\u2202']),
- ('\U0001d716', &['\u03f5']), ('\U0001d717', &['\u03d1']), ('\U0001d718', &['\u03f0']),
- ('\U0001d719', &['\u03d5']), ('\U0001d71a', &['\u03f1']), ('\U0001d71b', &['\u03d6']),
- ('\U0001d71c', &['\u0391']), ('\U0001d71d', &['\u0392']), ('\U0001d71e', &['\u0393']),
- ('\U0001d71f', &['\u0394']), ('\U0001d720', &['\u0395']), ('\U0001d721', &['\u0396']),
- ('\U0001d722', &['\u0397']), ('\U0001d723', &['\u0398']), ('\U0001d724', &['\u0399']),
- ('\U0001d725', &['\u039a']), ('\U0001d726', &['\u039b']), ('\U0001d727', &['\u039c']),
- ('\U0001d728', &['\u039d']), ('\U0001d729', &['\u039e']), ('\U0001d72a', &['\u039f']),
- ('\U0001d72b', &['\u03a0']), ('\U0001d72c', &['\u03a1']), ('\U0001d72d', &['\u03f4']),
- ('\U0001d72e', &['\u03a3']), ('\U0001d72f', &['\u03a4']), ('\U0001d730', &['\u03a5']),
- ('\U0001d731', &['\u03a6']), ('\U0001d732', &['\u03a7']), ('\U0001d733', &['\u03a8']),
- ('\U0001d734', &['\u03a9']), ('\U0001d735', &['\u2207']), ('\U0001d736', &['\u03b1']),
- ('\U0001d737', &['\u03b2']), ('\U0001d738', &['\u03b3']), ('\U0001d739', &['\u03b4']),
- ('\U0001d73a', &['\u03b5']), ('\U0001d73b', &['\u03b6']), ('\U0001d73c', &['\u03b7']),
- ('\U0001d73d', &['\u03b8']), ('\U0001d73e', &['\u03b9']), ('\U0001d73f', &['\u03ba']),
- ('\U0001d740', &['\u03bb']), ('\U0001d741', &['\u03bc']), ('\U0001d742', &['\u03bd']),
- ('\U0001d743', &['\u03be']), ('\U0001d744', &['\u03bf']), ('\U0001d745', &['\u03c0']),
- ('\U0001d746', &['\u03c1']), ('\U0001d747', &['\u03c2']), ('\U0001d748', &['\u03c3']),
- ('\U0001d749', &['\u03c4']), ('\U0001d74a', &['\u03c5']), ('\U0001d74b', &['\u03c6']),
- ('\U0001d74c', &['\u03c7']), ('\U0001d74d', &['\u03c8']), ('\U0001d74e', &['\u03c9']),
- ('\U0001d74f', &['\u2202']), ('\U0001d750', &['\u03f5']), ('\U0001d751', &['\u03d1']),
- ('\U0001d752', &['\u03f0']), ('\U0001d753', &['\u03d5']), ('\U0001d754', &['\u03f1']),
- ('\U0001d755', &['\u03d6']), ('\U0001d756', &['\u0391']), ('\U0001d757', &['\u0392']),
- ('\U0001d758', &['\u0393']), ('\U0001d759', &['\u0394']), ('\U0001d75a', &['\u0395']),
- ('\U0001d75b', &['\u0396']), ('\U0001d75c', &['\u0397']), ('\U0001d75d', &['\u0398']),
- ('\U0001d75e', &['\u0399']), ('\U0001d75f', &['\u039a']), ('\U0001d760', &['\u039b']),
- ('\U0001d761', &['\u039c']), ('\U0001d762', &['\u039d']), ('\U0001d763', &['\u039e']),
- ('\U0001d764', &['\u039f']), ('\U0001d765', &['\u03a0']), ('\U0001d766', &['\u03a1']),
- ('\U0001d767', &['\u03f4']), ('\U0001d768', &['\u03a3']), ('\U0001d769', &['\u03a4']),
- ('\U0001d76a', &['\u03a5']), ('\U0001d76b', &['\u03a6']), ('\U0001d76c', &['\u03a7']),
- ('\U0001d76d', &['\u03a8']), ('\U0001d76e', &['\u03a9']), ('\U0001d76f', &['\u2207']),
- ('\U0001d770', &['\u03b1']), ('\U0001d771', &['\u03b2']), ('\U0001d772', &['\u03b3']),
- ('\U0001d773', &['\u03b4']), ('\U0001d774', &['\u03b5']), ('\U0001d775', &['\u03b6']),
- ('\U0001d776', &['\u03b7']), ('\U0001d777', &['\u03b8']), ('\U0001d778', &['\u03b9']),
- ('\U0001d779', &['\u03ba']), ('\U0001d77a', &['\u03bb']), ('\U0001d77b', &['\u03bc']),
- ('\U0001d77c', &['\u03bd']), ('\U0001d77d', &['\u03be']), ('\U0001d77e', &['\u03bf']),
- ('\U0001d77f', &['\u03c0']), ('\U0001d780', &['\u03c1']), ('\U0001d781', &['\u03c2']),
- ('\U0001d782', &['\u03c3']), ('\U0001d783', &['\u03c4']), ('\U0001d784', &['\u03c5']),
- ('\U0001d785', &['\u03c6']), ('\U0001d786', &['\u03c7']), ('\U0001d787', &['\u03c8']),
- ('\U0001d788', &['\u03c9']), ('\U0001d789', &['\u2202']), ('\U0001d78a', &['\u03f5']),
- ('\U0001d78b', &['\u03d1']), ('\U0001d78c', &['\u03f0']), ('\U0001d78d', &['\u03d5']),
- ('\U0001d78e', &['\u03f1']), ('\U0001d78f', &['\u03d6']), ('\U0001d790', &['\u0391']),
- ('\U0001d791', &['\u0392']), ('\U0001d792', &['\u0393']), ('\U0001d793', &['\u0394']),
- ('\U0001d794', &['\u0395']), ('\U0001d795', &['\u0396']), ('\U0001d796', &['\u0397']),
- ('\U0001d797', &['\u0398']), ('\U0001d798', &['\u0399']), ('\U0001d799', &['\u039a']),
- ('\U0001d79a', &['\u039b']), ('\U0001d79b', &['\u039c']), ('\U0001d79c', &['\u039d']),
- ('\U0001d79d', &['\u039e']), ('\U0001d79e', &['\u039f']), ('\U0001d79f', &['\u03a0']),
- ('\U0001d7a0', &['\u03a1']), ('\U0001d7a1', &['\u03f4']), ('\U0001d7a2', &['\u03a3']),
- ('\U0001d7a3', &['\u03a4']), ('\U0001d7a4', &['\u03a5']), ('\U0001d7a5', &['\u03a6']),
- ('\U0001d7a6', &['\u03a7']), ('\U0001d7a7', &['\u03a8']), ('\U0001d7a8', &['\u03a9']),
- ('\U0001d7a9', &['\u2207']), ('\U0001d7aa', &['\u03b1']), ('\U0001d7ab', &['\u03b2']),
- ('\U0001d7ac', &['\u03b3']), ('\U0001d7ad', &['\u03b4']), ('\U0001d7ae', &['\u03b5']),
- ('\U0001d7af', &['\u03b6']), ('\U0001d7b0', &['\u03b7']), ('\U0001d7b1', &['\u03b8']),
- ('\U0001d7b2', &['\u03b9']), ('\U0001d7b3', &['\u03ba']), ('\U0001d7b4', &['\u03bb']),
- ('\U0001d7b5', &['\u03bc']), ('\U0001d7b6', &['\u03bd']), ('\U0001d7b7', &['\u03be']),
- ('\U0001d7b8', &['\u03bf']), ('\U0001d7b9', &['\u03c0']), ('\U0001d7ba', &['\u03c1']),
- ('\U0001d7bb', &['\u03c2']), ('\U0001d7bc', &['\u03c3']), ('\U0001d7bd', &['\u03c4']),
- ('\U0001d7be', &['\u03c5']), ('\U0001d7bf', &['\u03c6']), ('\U0001d7c0', &['\u03c7']),
- ('\U0001d7c1', &['\u03c8']), ('\U0001d7c2', &['\u03c9']), ('\U0001d7c3', &['\u2202']),
- ('\U0001d7c4', &['\u03f5']), ('\U0001d7c5', &['\u03d1']), ('\U0001d7c6', &['\u03f0']),
- ('\U0001d7c7', &['\u03d5']), ('\U0001d7c8', &['\u03f1']), ('\U0001d7c9', &['\u03d6']),
- ('\U0001d7ca', &['\u03dc']), ('\U0001d7cb', &['\u03dd']), ('\U0001d7ce', &['\x30']),
- ('\U0001d7cf', &['\x31']), ('\U0001d7d0', &['\x32']), ('\U0001d7d1', &['\x33']),
- ('\U0001d7d2', &['\x34']), ('\U0001d7d3', &['\x35']), ('\U0001d7d4', &['\x36']),
- ('\U0001d7d5', &['\x37']), ('\U0001d7d6', &['\x38']), ('\U0001d7d7', &['\x39']),
- ('\U0001d7d8', &['\x30']), ('\U0001d7d9', &['\x31']), ('\U0001d7da', &['\x32']),
- ('\U0001d7db', &['\x33']), ('\U0001d7dc', &['\x34']), ('\U0001d7dd', &['\x35']),
- ('\U0001d7de', &['\x36']), ('\U0001d7df', &['\x37']), ('\U0001d7e0', &['\x38']),
- ('\U0001d7e1', &['\x39']), ('\U0001d7e2', &['\x30']), ('\U0001d7e3', &['\x31']),
- ('\U0001d7e4', &['\x32']), ('\U0001d7e5', &['\x33']), ('\U0001d7e6', &['\x34']),
- ('\U0001d7e7', &['\x35']), ('\U0001d7e8', &['\x36']), ('\U0001d7e9', &['\x37']),
- ('\U0001d7ea', &['\x38']), ('\U0001d7eb', &['\x39']), ('\U0001d7ec', &['\x30']),
- ('\U0001d7ed', &['\x31']), ('\U0001d7ee', &['\x32']), ('\U0001d7ef', &['\x33']),
- ('\U0001d7f0', &['\x34']), ('\U0001d7f1', &['\x35']), ('\U0001d7f2', &['\x36']),
- ('\U0001d7f3', &['\x37']), ('\U0001d7f4', &['\x38']), ('\U0001d7f5', &['\x39']),
- ('\U0001d7f6', &['\x30']), ('\U0001d7f7', &['\x31']), ('\U0001d7f8', &['\x32']),
- ('\U0001d7f9', &['\x33']), ('\U0001d7fa', &['\x34']), ('\U0001d7fb', &['\x35']),
- ('\U0001d7fc', &['\x36']), ('\U0001d7fd', &['\x37']), ('\U0001d7fe', &['\x38']),
- ('\U0001d7ff', &['\x39']), ('\U0001ee00', &['\u0627']), ('\U0001ee01', &['\u0628']),
- ('\U0001ee02', &['\u062c']), ('\U0001ee03', &['\u062f']), ('\U0001ee05', &['\u0648']),
- ('\U0001ee06', &['\u0632']), ('\U0001ee07', &['\u062d']), ('\U0001ee08', &['\u0637']),
- ('\U0001ee09', &['\u064a']), ('\U0001ee0a', &['\u0643']), ('\U0001ee0b', &['\u0644']),
- ('\U0001ee0c', &['\u0645']), ('\U0001ee0d', &['\u0646']), ('\U0001ee0e', &['\u0633']),
- ('\U0001ee0f', &['\u0639']), ('\U0001ee10', &['\u0641']), ('\U0001ee11', &['\u0635']),
- ('\U0001ee12', &['\u0642']), ('\U0001ee13', &['\u0631']), ('\U0001ee14', &['\u0634']),
- ('\U0001ee15', &['\u062a']), ('\U0001ee16', &['\u062b']), ('\U0001ee17', &['\u062e']),
- ('\U0001ee18', &['\u0630']), ('\U0001ee19', &['\u0636']), ('\U0001ee1a', &['\u0638']),
- ('\U0001ee1b', &['\u063a']), ('\U0001ee1c', &['\u066e']), ('\U0001ee1d', &['\u06ba']),
- ('\U0001ee1e', &['\u06a1']), ('\U0001ee1f', &['\u066f']), ('\U0001ee21', &['\u0628']),
- ('\U0001ee22', &['\u062c']), ('\U0001ee24', &['\u0647']), ('\U0001ee27', &['\u062d']),
- ('\U0001ee29', &['\u064a']), ('\U0001ee2a', &['\u0643']), ('\U0001ee2b', &['\u0644']),
- ('\U0001ee2c', &['\u0645']), ('\U0001ee2d', &['\u0646']), ('\U0001ee2e', &['\u0633']),
- ('\U0001ee2f', &['\u0639']), ('\U0001ee30', &['\u0641']), ('\U0001ee31', &['\u0635']),
- ('\U0001ee32', &['\u0642']), ('\U0001ee34', &['\u0634']), ('\U0001ee35', &['\u062a']),
- ('\U0001ee36', &['\u062b']), ('\U0001ee37', &['\u062e']), ('\U0001ee39', &['\u0636']),
- ('\U0001ee3b', &['\u063a']), ('\U0001ee42', &['\u062c']), ('\U0001ee47', &['\u062d']),
- ('\U0001ee49', &['\u064a']), ('\U0001ee4b', &['\u0644']), ('\U0001ee4d', &['\u0646']),
- ('\U0001ee4e', &['\u0633']), ('\U0001ee4f', &['\u0639']), ('\U0001ee51', &['\u0635']),
- ('\U0001ee52', &['\u0642']), ('\U0001ee54', &['\u0634']), ('\U0001ee57', &['\u062e']),
- ('\U0001ee59', &['\u0636']), ('\U0001ee5b', &['\u063a']), ('\U0001ee5d', &['\u06ba']),
- ('\U0001ee5f', &['\u066f']), ('\U0001ee61', &['\u0628']), ('\U0001ee62', &['\u062c']),
- ('\U0001ee64', &['\u0647']), ('\U0001ee67', &['\u062d']), ('\U0001ee68', &['\u0637']),
- ('\U0001ee69', &['\u064a']), ('\U0001ee6a', &['\u0643']), ('\U0001ee6c', &['\u0645']),
- ('\U0001ee6d', &['\u0646']), ('\U0001ee6e', &['\u0633']), ('\U0001ee6f', &['\u0639']),
- ('\U0001ee70', &['\u0641']), ('\U0001ee71', &['\u0635']), ('\U0001ee72', &['\u0642']),
- ('\U0001ee74', &['\u0634']), ('\U0001ee75', &['\u062a']), ('\U0001ee76', &['\u062b']),
- ('\U0001ee77', &['\u062e']), ('\U0001ee79', &['\u0636']), ('\U0001ee7a', &['\u0638']),
- ('\U0001ee7b', &['\u063a']), ('\U0001ee7c', &['\u066e']), ('\U0001ee7e', &['\u06a1']),
- ('\U0001ee80', &['\u0627']), ('\U0001ee81', &['\u0628']), ('\U0001ee82', &['\u062c']),
- ('\U0001ee83', &['\u062f']), ('\U0001ee84', &['\u0647']), ('\U0001ee85', &['\u0648']),
- ('\U0001ee86', &['\u0632']), ('\U0001ee87', &['\u062d']), ('\U0001ee88', &['\u0637']),
- ('\U0001ee89', &['\u064a']), ('\U0001ee8b', &['\u0644']), ('\U0001ee8c', &['\u0645']),
- ('\U0001ee8d', &['\u0646']), ('\U0001ee8e', &['\u0633']), ('\U0001ee8f', &['\u0639']),
- ('\U0001ee90', &['\u0641']), ('\U0001ee91', &['\u0635']), ('\U0001ee92', &['\u0642']),
- ('\U0001ee93', &['\u0631']), ('\U0001ee94', &['\u0634']), ('\U0001ee95', &['\u062a']),
- ('\U0001ee96', &['\u062b']), ('\U0001ee97', &['\u062e']), ('\U0001ee98', &['\u0630']),
- ('\U0001ee99', &['\u0636']), ('\U0001ee9a', &['\u0638']), ('\U0001ee9b', &['\u063a']),
- ('\U0001eea1', &['\u0628']), ('\U0001eea2', &['\u062c']), ('\U0001eea3', &['\u062f']),
- ('\U0001eea5', &['\u0648']), ('\U0001eea6', &['\u0632']), ('\U0001eea7', &['\u062d']),
- ('\U0001eea8', &['\u0637']), ('\U0001eea9', &['\u064a']), ('\U0001eeab', &['\u0644']),
- ('\U0001eeac', &['\u0645']), ('\U0001eead', &['\u0646']), ('\U0001eeae', &['\u0633']),
- ('\U0001eeaf', &['\u0639']), ('\U0001eeb0', &['\u0641']), ('\U0001eeb1', &['\u0635']),
- ('\U0001eeb2', &['\u0642']), ('\U0001eeb3', &['\u0631']), ('\U0001eeb4', &['\u0634']),
- ('\U0001eeb5', &['\u062a']), ('\U0001eeb6', &['\u062b']), ('\U0001eeb7', &['\u062e']),
- ('\U0001eeb8', &['\u0630']), ('\U0001eeb9', &['\u0636']), ('\U0001eeba', &['\u0638']),
- ('\U0001eebb', &['\u063a']), ('\U0001f100', &['\x30', '\x2e']), ('\U0001f101', &['\x30',
- '\x2c']), ('\U0001f102', &['\x31', '\x2c']), ('\U0001f103', &['\x32', '\x2c']),
- ('\U0001f104', &['\x33', '\x2c']), ('\U0001f105', &['\x34', '\x2c']), ('\U0001f106',
- &['\x35', '\x2c']), ('\U0001f107', &['\x36', '\x2c']), ('\U0001f108', &['\x37', '\x2c']),
- ('\U0001f109', &['\x38', '\x2c']), ('\U0001f10a', &['\x39', '\x2c']), ('\U0001f110',
- &['\x28', '\x41', '\x29']), ('\U0001f111', &['\x28', '\x42', '\x29']), ('\U0001f112',
- &['\x28', '\x43', '\x29']), ('\U0001f113', &['\x28', '\x44', '\x29']), ('\U0001f114',
- &['\x28', '\x45', '\x29']), ('\U0001f115', &['\x28', '\x46', '\x29']), ('\U0001f116',
- &['\x28', '\x47', '\x29']), ('\U0001f117', &['\x28', '\x48', '\x29']), ('\U0001f118',
- &['\x28', '\x49', '\x29']), ('\U0001f119', &['\x28', '\x4a', '\x29']), ('\U0001f11a',
- &['\x28', '\x4b', '\x29']), ('\U0001f11b', &['\x28', '\x4c', '\x29']), ('\U0001f11c',
- &['\x28', '\x4d', '\x29']), ('\U0001f11d', &['\x28', '\x4e', '\x29']), ('\U0001f11e',
- &['\x28', '\x4f', '\x29']), ('\U0001f11f', &['\x28', '\x50', '\x29']), ('\U0001f120',
- &['\x28', '\x51', '\x29']), ('\U0001f121', &['\x28', '\x52', '\x29']), ('\U0001f122',
- &['\x28', '\x53', '\x29']), ('\U0001f123', &['\x28', '\x54', '\x29']), ('\U0001f124',
- &['\x28', '\x55', '\x29']), ('\U0001f125', &['\x28', '\x56', '\x29']), ('\U0001f126',
- &['\x28', '\x57', '\x29']), ('\U0001f127', &['\x28', '\x58', '\x29']), ('\U0001f128',
- &['\x28', '\x59', '\x29']), ('\U0001f129', &['\x28', '\x5a', '\x29']), ('\U0001f12a',
- &['\u3014', '\x53', '\u3015']), ('\U0001f12b', &['\x43']), ('\U0001f12c', &['\x52']),
- ('\U0001f12d', &['\x43', '\x44']), ('\U0001f12e', &['\x57', '\x5a']), ('\U0001f130',
- &['\x41']), ('\U0001f131', &['\x42']), ('\U0001f132', &['\x43']), ('\U0001f133', &['\x44']),
- ('\U0001f134', &['\x45']), ('\U0001f135', &['\x46']), ('\U0001f136', &['\x47']),
- ('\U0001f137', &['\x48']), ('\U0001f138', &['\x49']), ('\U0001f139', &['\x4a']),
- ('\U0001f13a', &['\x4b']), ('\U0001f13b', &['\x4c']), ('\U0001f13c', &['\x4d']),
- ('\U0001f13d', &['\x4e']), ('\U0001f13e', &['\x4f']), ('\U0001f13f', &['\x50']),
- ('\U0001f140', &['\x51']), ('\U0001f141', &['\x52']), ('\U0001f142', &['\x53']),
- ('\U0001f143', &['\x54']), ('\U0001f144', &['\x55']), ('\U0001f145', &['\x56']),
- ('\U0001f146', &['\x57']), ('\U0001f147', &['\x58']), ('\U0001f148', &['\x59']),
- ('\U0001f149', &['\x5a']), ('\U0001f14a', &['\x48', '\x56']), ('\U0001f14b', &['\x4d',
- '\x56']), ('\U0001f14c', &['\x53', '\x44']), ('\U0001f14d', &['\x53', '\x53']),
- ('\U0001f14e', &['\x50', '\x50', '\x56']), ('\U0001f14f', &['\x57', '\x43']), ('\U0001f16a',
- &['\x4d', '\x43']), ('\U0001f16b', &['\x4d', '\x44']), ('\U0001f190', &['\x44', '\x4a']),
- ('\U0001f200', &['\u307b', '\u304b']), ('\U0001f201', &['\u30b3', '\u30b3']), ('\U0001f202',
- &['\u30b5']), ('\U0001f210', &['\u624b']), ('\U0001f211', &['\u5b57']), ('\U0001f212',
- &['\u53cc']), ('\U0001f213', &['\u30c7']), ('\U0001f214', &['\u4e8c']), ('\U0001f215',
- &['\u591a']), ('\U0001f216', &['\u89e3']), ('\U0001f217', &['\u5929']), ('\U0001f218',
- &['\u4ea4']), ('\U0001f219', &['\u6620']), ('\U0001f21a', &['\u7121']), ('\U0001f21b',
- &['\u6599']), ('\U0001f21c', &['\u524d']), ('\U0001f21d', &['\u5f8c']), ('\U0001f21e',
- &['\u518d']), ('\U0001f21f', &['\u65b0']), ('\U0001f220', &['\u521d']), ('\U0001f221',
- &['\u7d42']), ('\U0001f222', &['\u751f']), ('\U0001f223', &['\u8ca9']), ('\U0001f224',
- &['\u58f0']), ('\U0001f225', &['\u5439']), ('\U0001f226', &['\u6f14']), ('\U0001f227',
- &['\u6295']), ('\U0001f228', &['\u6355']), ('\U0001f229', &['\u4e00']), ('\U0001f22a',
- &['\u4e09']), ('\U0001f22b', &['\u904a']), ('\U0001f22c', &['\u5de6']), ('\U0001f22d',
- &['\u4e2d']), ('\U0001f22e', &['\u53f3']), ('\U0001f22f', &['\u6307']), ('\U0001f230',
- &['\u8d70']), ('\U0001f231', &['\u6253']), ('\U0001f232', &['\u7981']), ('\U0001f233',
- &['\u7a7a']), ('\U0001f234', &['\u5408']), ('\U0001f235', &['\u6e80']), ('\U0001f236',
- &['\u6709']), ('\U0001f237', &['\u6708']), ('\U0001f238', &['\u7533']), ('\U0001f239',
- &['\u5272']), ('\U0001f23a', &['\u55b6']), ('\U0001f240', &['\u3014', '\u672c', '\u3015']),
- ('\U0001f241', &['\u3014', '\u4e09', '\u3015']), ('\U0001f242', &['\u3014', '\u4e8c',
- '\u3015']), ('\U0001f243', &['\u3014', '\u5b89', '\u3015']), ('\U0001f244', &['\u3014',
- '\u70b9', '\u3015']), ('\U0001f245', &['\u3014', '\u6253', '\u3015']), ('\U0001f246',
- &['\u3014', '\u76d7', '\u3015']), ('\U0001f247', &['\u3014', '\u52dd', '\u3015']),
- ('\U0001f248', &['\u3014', '\u6557', '\u3015']), ('\U0001f250', &['\u5f97']), ('\U0001f251',
- &['\u53ef'])
- ];
-
- static combining_class_table : &'static [(char, char, u8)] = &[
- ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232),
- ('\u0316', '\u0319', 220), ('\u031a', '\u031a', 232),
- ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220),
- ('\u0321', '\u0322', 202), ('\u0323', '\u0326', 220),
- ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
- ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220),
- ('\u033d', '\u0344', 230), ('\u0345', '\u0345', 240),
- ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220),
- ('\u034a', '\u034c', 230), ('\u034d', '\u034e', 220),
- ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
- ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232),
- ('\u0359', '\u035a', 220), ('\u035b', '\u035b', 230),
- ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234),
- ('\u035f', '\u035f', 233), ('\u0360', '\u0361', 234),
- ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
- ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220),
- ('\u0592', '\u0595', 230), ('\u0596', '\u0596', 220),
- ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222),
- ('\u059b', '\u059b', 220), ('\u059c', '\u05a1', 230),
- ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
- ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230),
- ('\u05ad', '\u05ad', 222), ('\u05ae', '\u05ae', 228),
- ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10),
- ('\u05b1', '\u05b1', 11), ('\u05b2', '\u05b2', 12),
- ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
- ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16),
- ('\u05b7', '\u05b7', 17), ('\u05b8', '\u05b8', 18),
- ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20),
- ('\u05bc', '\u05bc', 21), ('\u05bd', '\u05bd', 22),
- ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24),
- ('\u05c2', '\u05c2', 25), ('\u05c4', '\u05c4', 230),
- ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7', 18),
- ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30),
- ('\u0619', '\u0619', 31), ('\u061a', '\u061a', 32),
- ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28),
- ('\u064d', '\u064d', 29), ('\u064e', '\u064e', 30),
- ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
- ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34),
- ('\u0653', '\u0654', 230), ('\u0655', '\u0656', 220),
- ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220),
- ('\u065d', '\u065e', 230), ('\u065f', '\u065f', 220),
- ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
- ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220),
- ('\u06e4', '\u06e4', 230), ('\u06e7', '\u06e8', 230),
- ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230),
- ('\u06ed', '\u06ed', 220), ('\u0711', '\u0711', 36),
- ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
- ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220),
- ('\u0735', '\u0736', 230), ('\u0737', '\u0739', 220),
- ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220),
- ('\u073d', '\u073d', 230), ('\u073e', '\u073e', 220),
- ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
- ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220),
- ('\u0745', '\u0745', 230), ('\u0746', '\u0746', 220),
- ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220),
- ('\u0749', '\u074a', 230), ('\u07eb', '\u07f1', 230),
- ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
- ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230),
- ('\u0825', '\u0827', 230), ('\u0829', '\u082d', 230),
- ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230),
- ('\u08e6', '\u08e6', 220), ('\u08e7', '\u08e8', 230),
- ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
- ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27),
- ('\u08f1', '\u08f1', 28), ('\u08f2', '\u08f2', 29),
- ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220),
- ('\u08f7', '\u08f8', 230), ('\u08f9', '\u08fa', 220),
- ('\u08fb', '\u08fe', 230), ('\u093c', '\u093c', 7),
- ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230),
- ('\u0952', '\u0952', 220), ('\u0953', '\u0954', 230),
- ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9),
- ('\u0a3c', '\u0a3c', 7), ('\u0a4d', '\u0a4d', 9),
- ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9),
- ('\u0b3c', '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9),
- ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
- ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91),
- ('\u0cbc', '\u0cbc', 7), ('\u0ccd', '\u0ccd', 9),
- ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9),
- ('\u0e38', '\u0e39', 103), ('\u0e3a', '\u0e3a', 9),
- ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118),
- ('\u0ec8', '\u0ecb', 122), ('\u0f18', '\u0f19', 220),
- ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37', 220),
- ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129),
- ('\u0f72', '\u0f72', 130), ('\u0f74', '\u0f74', 132),
- ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130),
- ('\u0f82', '\u0f83', 230), ('\u0f84', '\u0f84', 9),
- ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6', 220),
- ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9),
- ('\u108d', '\u108d', 220), ('\u135d', '\u135f', 230),
- ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9),
- ('\u17d2', '\u17d2', 9), ('\u17dd', '\u17dd', 230),
- ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939', 222),
- ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220),
- ('\u1a17', '\u1a17', 230), ('\u1a18', '\u1a18', 220),
- ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230),
- ('\u1a7f', '\u1a7f', 220), ('\u1b34', '\u1b34', 7),
- ('\u1b44', '\u1b44', 9), ('\u1b6b', '\u1b6b', 230),
- ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230),
- ('\u1baa', '\u1bab', 9), ('\u1be6', '\u1be6', 7),
- ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
- ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1),
- ('\u1cd5', '\u1cd9', 220), ('\u1cda', '\u1cdb', 230),
- ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230),
- ('\u1ce2', '\u1ce8', 1), ('\u1ced', '\u1ced', 220),
- ('\u1cf4', '\u1cf4', 230), ('\u1dc0', '\u1dc1', 230),
- ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230),
- ('\u1dca', '\u1dca', 220), ('\u1dcb', '\u1dcc', 230),
- ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce', 214),
- ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202),
- ('\u1dd1', '\u1de6', 230), ('\u1dfc', '\u1dfc', 233),
- ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230),
- ('\u1dff', '\u1dff', 220), ('\u20d0', '\u20d1', 230),
- ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7', 230),
- ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230),
- ('\u20e1', '\u20e1', 230), ('\u20e5', '\u20e6', 1),
- ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220),
- ('\u20e9', '\u20e9', 230), ('\u20ea', '\u20eb', 1),
- ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0', 230),
- ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9),
- ('\u2de0', '\u2dff', 230), ('\u302a', '\u302a', 218),
- ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232),
- ('\u302d', '\u302d', 222), ('\u302e', '\u302f', 224),
- ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f', 230),
- ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230),
- ('\ua6f0', '\ua6f1', 230), ('\ua806', '\ua806', 9),
- ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230),
- ('\ua92b', '\ua92d', 220), ('\ua953', '\ua953', 9),
- ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
- ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230),
- ('\uaab4', '\uaab4', 220), ('\uaab7', '\uaab8', 230),
- ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230),
- ('\uaaf6', '\uaaf6', 9), ('\uabed', '\uabed', 9),
- ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230),
- ('\U000101fd', '\U000101fd', 220), ('\U00010a0d', '\U00010a0d', 220),
- ('\U00010a0f', '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230),
- ('\U00010a39', '\U00010a39', 1), ('\U00010a3a', '\U00010a3a', 220),
- ('\U00010a3f', '\U00010a3f', 9), ('\U00011046', '\U00011046', 9),
- ('\U000110b9', '\U000110b9', 9), ('\U000110ba', '\U000110ba', 7),
- ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
- ('\U000111c0', '\U000111c0', 9), ('\U000116b6', '\U000116b6', 9),
- ('\U000116b7', '\U000116b7', 7), ('\U0001d165', '\U0001d166', 216),
- ('\U0001d167', '\U0001d169', 1), ('\U0001d16d', '\U0001d16d', 226),
- ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
- ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220),
- ('\U0001d1aa', '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230)
- ];
- pub fn canonical(c: char, i: |char|) { d(c, i, false); }
-
- pub fn compatibility(c: char, i: |char|) { d(c, i, true); }
-
- pub fn canonical_combining_class(c: char) -> u8 {
- bsearch_range_value_table(c, combining_class_table)
- }
-
- fn d(c: char, i: |char|, k: bool) {
- use iter::Iterator;
- if c <= '\x7f' { i(c); return; }
-
- match bsearch_table(c, canonical_table) {
- Some(canon) => {
- for x in canon.iter() {
- d(*x, |b| i(b), k);
- }
- return;
- }
- None => ()
- }
-
- if !k { i(c); return; }
-
- match bsearch_table(c, compatibility_table) {
- Some(compat) => {
- for x in compat.iter() {
- d(*x, |b| i(b), k);
- }
- return;
- }
- None => ()
- }
-
- i(c);
- }
-}
-
-pub mod derived_property {
-
- fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
- use cmp::{Equal, Less, Greater};
- use vec::ImmutableVector;
- use option::None;
- r.bsearch(|&(lo,hi)| {
- if lo <= c && c <= hi { Equal }
- else if hi < c { Less }
- else { Greater }
- }) != None
- }
-
-
- static Alphabetic_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\x61', '\x7a'),
- ('\xaa', '\xaa'), ('\xb5', '\xb5'),
- ('\xba', '\xba'), ('\xc0', '\xd6'),
- ('\xd8', '\xf6'), ('\xf8', '\u01ba'),
- ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'),
- ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'),
- ('\u0294', '\u0294'), ('\u0295', '\u02af'),
- ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
- ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
- ('\u02ee', '\u02ee'), ('\u0345', '\u0345'),
- ('\u0370', '\u0373'), ('\u0374', '\u0374'),
- ('\u0376', '\u0377'), ('\u037a', '\u037a'),
- ('\u037b', '\u037d'), ('\u0386', '\u0386'),
- ('\u0388', '\u038a'), ('\u038c', '\u038c'),
- ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
- ('\u03f7', '\u0481'), ('\u048a', '\u0527'),
- ('\u0531', '\u0556'), ('\u0559', '\u0559'),
- ('\u0561', '\u0587'), ('\u05b0', '\u05bd'),
- ('\u05bf', '\u05bf'), ('\u05c1', '\u05c2'),
- ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'),
- ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'),
- ('\u0610', '\u061a'), ('\u0620', '\u063f'),
- ('\u0640', '\u0640'), ('\u0641', '\u064a'),
- ('\u064b', '\u0657'), ('\u0659', '\u065f'),
- ('\u066e', '\u066f'), ('\u0670', '\u0670'),
- ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'),
- ('\u06d6', '\u06dc'), ('\u06e1', '\u06e4'),
- ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'),
- ('\u06ed', '\u06ed'), ('\u06ee', '\u06ef'),
- ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'),
- ('\u0710', '\u0710'), ('\u0711', '\u0711'),
- ('\u0712', '\u072f'), ('\u0730', '\u073f'),
- ('\u074d', '\u07a5'), ('\u07a6', '\u07b0'),
- ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'),
- ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
- ('\u0800', '\u0815'), ('\u0816', '\u0817'),
- ('\u081a', '\u081a'), ('\u081b', '\u0823'),
- ('\u0824', '\u0824'), ('\u0825', '\u0827'),
- ('\u0828', '\u0828'), ('\u0829', '\u082c'),
- ('\u0840', '\u0858'), ('\u08a0', '\u08a0'),
- ('\u08a2', '\u08ac'), ('\u08e4', '\u08e9'),
- ('\u08f0', '\u08fe'), ('\u0900', '\u0902'),
- ('\u0903', '\u0903'), ('\u0904', '\u0939'),
- ('\u093a', '\u093a'), ('\u093b', '\u093b'),
- ('\u093d', '\u093d'), ('\u093e', '\u0940'),
- ('\u0941', '\u0948'), ('\u0949', '\u094c'),
- ('\u094e', '\u094f'), ('\u0950', '\u0950'),
- ('\u0955', '\u0957'), ('\u0958', '\u0961'),
- ('\u0962', '\u0963'), ('\u0971', '\u0971'),
- ('\u0972', '\u0977'), ('\u0979', '\u097f'),
- ('\u0981', '\u0981'), ('\u0982', '\u0983'),
- ('\u0985', '\u098c'), ('\u098f', '\u0990'),
- ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
- ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
- ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'),
- ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'),
- ('\u09cb', '\u09cc'), ('\u09ce', '\u09ce'),
- ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
- ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'),
- ('\u09f0', '\u09f1'), ('\u0a01', '\u0a02'),
- ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'),
- ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'),
- ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'),
- ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'),
- ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
- ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4c'),
- ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
- ('\u0a5e', '\u0a5e'), ('\u0a70', '\u0a71'),
- ('\u0a72', '\u0a74'), ('\u0a75', '\u0a75'),
- ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'),
- ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'),
- ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'),
- ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'),
- ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
- ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'),
- ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
- ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'),
- ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b01'),
- ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
- ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
- ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
- ('\u0b35', '\u0b39'), ('\u0b3d', '\u0b3d'),
- ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'),
- ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'),
- ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'),
- ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
- ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'),
- ('\u0b62', '\u0b63'), ('\u0b71', '\u0b71'),
- ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'),
- ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'),
- ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'),
- ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'),
- ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'),
- ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bbf'),
- ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'),
- ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'),
- ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
- ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'),
- ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'),
- ('\u0c2a', '\u0c33'), ('\u0c35', '\u0c39'),
- ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'),
- ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'),
- ('\u0c4a', '\u0c4c'), ('\u0c55', '\u0c56'),
- ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'),
- ('\u0c62', '\u0c63'), ('\u0c82', '\u0c83'),
- ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
- ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
- ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'),
- ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'),
- ('\u0cc0', '\u0cc4'), ('\u0cc6', '\u0cc6'),
- ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'),
- ('\u0ccc', '\u0ccc'), ('\u0cd5', '\u0cd6'),
- ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'),
- ('\u0ce2', '\u0ce3'), ('\u0cf1', '\u0cf2'),
- ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'),
- ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
- ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'),
- ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
- ('\u0d4a', '\u0d4c'), ('\u0d4e', '\u0d4e'),
- ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'),
- ('\u0d62', '\u0d63'), ('\u0d7a', '\u0d7f'),
- ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'),
- ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
- ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
- ('\u0dcf', '\u0dd1'), ('\u0dd2', '\u0dd4'),
- ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'),
- ('\u0df2', '\u0df3'), ('\u0e01', '\u0e30'),
- ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'),
- ('\u0e34', '\u0e3a'), ('\u0e40', '\u0e45'),
- ('\u0e46', '\u0e46'), ('\u0e4d', '\u0e4d'),
- ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
- ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
- ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
- ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
- ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
- ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
- ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'),
- ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
- ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'),
- ('\u0ec6', '\u0ec6'), ('\u0ecd', '\u0ecd'),
- ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
- ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
- ('\u0f71', '\u0f7e'), ('\u0f7f', '\u0f7f'),
- ('\u0f80', '\u0f81'), ('\u0f88', '\u0f8c'),
- ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'),
- ('\u1000', '\u102a'), ('\u102b', '\u102c'),
- ('\u102d', '\u1030'), ('\u1031', '\u1031'),
- ('\u1032', '\u1036'), ('\u1038', '\u1038'),
- ('\u103b', '\u103c'), ('\u103d', '\u103e'),
- ('\u103f', '\u103f'), ('\u1050', '\u1055'),
- ('\u1056', '\u1057'), ('\u1058', '\u1059'),
- ('\u105a', '\u105d'), ('\u105e', '\u1060'),
- ('\u1061', '\u1061'), ('\u1062', '\u1062'),
- ('\u1065', '\u1066'), ('\u1067', '\u1068'),
- ('\u106e', '\u1070'), ('\u1071', '\u1074'),
- ('\u1075', '\u1081'), ('\u1082', '\u1082'),
- ('\u1083', '\u1084'), ('\u1085', '\u1086'),
- ('\u108e', '\u108e'), ('\u109c', '\u109c'),
- ('\u109d', '\u109d'), ('\u10a0', '\u10c5'),
- ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
- ('\u10d0', '\u10fa'), ('\u10fc', '\u10fc'),
- ('\u10fd', '\u1248'), ('\u124a', '\u124d'),
- ('\u1250', '\u1256'), ('\u1258', '\u1258'),
- ('\u125a', '\u125d'), ('\u1260', '\u1288'),
- ('\u128a', '\u128d'), ('\u1290', '\u12b0'),
- ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'),
- ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'),
- ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'),
- ('\u1312', '\u1315'), ('\u1318', '\u135a'),
- ('\u135f', '\u135f'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
- ('\u1700', '\u170c'), ('\u170e', '\u1711'),
- ('\u1712', '\u1713'), ('\u1720', '\u1731'),
- ('\u1732', '\u1733'), ('\u1740', '\u1751'),
- ('\u1752', '\u1753'), ('\u1760', '\u176c'),
- ('\u176e', '\u1770'), ('\u1772', '\u1773'),
- ('\u1780', '\u17b3'), ('\u17b6', '\u17b6'),
- ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'),
- ('\u17c6', '\u17c6'), ('\u17c7', '\u17c8'),
- ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
- ('\u1820', '\u1842'), ('\u1843', '\u1843'),
- ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
- ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'),
- ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
- ('\u1920', '\u1922'), ('\u1923', '\u1926'),
- ('\u1927', '\u1928'), ('\u1929', '\u192b'),
- ('\u1930', '\u1931'), ('\u1932', '\u1932'),
- ('\u1933', '\u1938'), ('\u1950', '\u196d'),
- ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
- ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'),
- ('\u19c8', '\u19c9'), ('\u1a00', '\u1a16'),
- ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
- ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'),
- ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
- ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'),
- ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'),
- ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'),
- ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a74'),
- ('\u1aa7', '\u1aa7'), ('\u1b00', '\u1b03'),
- ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'),
- ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'),
- ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'),
- ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'),
- ('\u1b43', '\u1b43'), ('\u1b45', '\u1b4b'),
- ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'),
- ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
- ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'),
- ('\u1ba8', '\u1ba9'), ('\u1bac', '\u1bad'),
- ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'),
- ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'),
- ('\u1bea', '\u1bec'), ('\u1bed', '\u1bed'),
- ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'),
- ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'),
- ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
- ('\u1c4d', '\u1c4f'), ('\u1c5a', '\u1c77'),
- ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'),
- ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'),
- ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'),
- ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
- ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
- ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'),
- ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
- ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
- ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
- ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
- ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
- ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
- ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
- ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
- ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
- ('\u2071', '\u2071'), ('\u207f', '\u207f'),
- ('\u2090', '\u209c'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210a', '\u2113'),
- ('\u2115', '\u2115'), ('\u2119', '\u211d'),
- ('\u2124', '\u2124'), ('\u2126', '\u2126'),
- ('\u2128', '\u2128'), ('\u212a', '\u212d'),
- ('\u212f', '\u2134'), ('\u2135', '\u2138'),
- ('\u2139', '\u2139'), ('\u213c', '\u213f'),
- ('\u2145', '\u2149'), ('\u214e', '\u214e'),
- ('\u2160', '\u2182'), ('\u2183', '\u2184'),
- ('\u2185', '\u2188'), ('\u24b6', '\u24e9'),
- ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'),
- ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'),
- ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'),
- ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
- ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
- ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'),
- ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'),
- ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'),
- ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'),
- ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'),
- ('\u2dd8', '\u2dde'), ('\u2de0', '\u2dff'),
- ('\u2e2f', '\u2e2f'), ('\u3005', '\u3005'),
- ('\u3006', '\u3006'), ('\u3007', '\u3007'),
- ('\u3021', '\u3029'), ('\u3031', '\u3035'),
- ('\u3038', '\u303a'), ('\u303b', '\u303b'),
- ('\u303c', '\u303c'), ('\u3041', '\u3096'),
- ('\u309d', '\u309e'), ('\u309f', '\u309f'),
- ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'),
- ('\u30ff', '\u30ff'), ('\u3105', '\u312d'),
- ('\u3131', '\u318e'), ('\u31a0', '\u31ba'),
- ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'),
- ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'),
- ('\ua015', '\ua015'), ('\ua016', '\ua48c'),
- ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'),
- ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'),
- ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'),
- ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'),
- ('\ua674', '\ua67b'), ('\ua67f', '\ua67f'),
- ('\ua680', '\ua697'), ('\ua69f', '\ua69f'),
- ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'),
- ('\ua717', '\ua71f'), ('\ua722', '\ua76f'),
- ('\ua770', '\ua770'), ('\ua771', '\ua787'),
- ('\ua788', '\ua788'), ('\ua78b', '\ua78e'),
- ('\ua790', '\ua793'), ('\ua7a0', '\ua7aa'),
- ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
- ('\ua7fb', '\ua801'), ('\ua803', '\ua805'),
- ('\ua807', '\ua80a'), ('\ua80c', '\ua822'),
- ('\ua823', '\ua824'), ('\ua825', '\ua826'),
- ('\ua827', '\ua827'), ('\ua840', '\ua873'),
- ('\ua880', '\ua881'), ('\ua882', '\ua8b3'),
- ('\ua8b4', '\ua8c3'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
- ('\ua926', '\ua92a'), ('\ua930', '\ua946'),
- ('\ua947', '\ua951'), ('\ua952', '\ua952'),
- ('\ua960', '\ua97c'), ('\ua980', '\ua982'),
- ('\ua983', '\ua983'), ('\ua984', '\ua9b2'),
- ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'),
- ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
- ('\ua9bd', '\ua9bf'), ('\ua9cf', '\ua9cf'),
- ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'),
- ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'),
- ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'),
- ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'),
- ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'),
- ('\uaa4d', '\uaa4d'), ('\uaa60', '\uaa6f'),
- ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
- ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'),
- ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'),
- ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'),
- ('\uaabe', '\uaabe'), ('\uaac0', '\uaac0'),
- ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
- ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
- ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'),
- ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'),
- ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
- ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
- ('\uab11', '\uab16'), ('\uab20', '\uab26'),
- ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'),
- ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'),
- ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'),
- ('\uabe9', '\uabea'), ('\uac00', '\ud7a3'),
- ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
- ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
- ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
- ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
- ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
- ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
- ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
- ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'),
- ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'),
- ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'),
- ('\ufe76', '\ufefc'), ('\uff21', '\uff3a'),
- ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
- ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
- ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
- ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
- ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
- ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
- ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'),
- ('\U00010300', '\U0001031e'), ('\U00010330', '\U00010340'),
- ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
- ('\U0001034a', '\U0001034a'), ('\U00010380', '\U0001039d'),
- ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'),
- ('\U000103d1', '\U000103d5'), ('\U00010400', '\U0001044f'),
- ('\U00010450', '\U0001049d'), ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'), ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'),
- ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
- ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
- ('\U00011003', '\U00011037'), ('\U00011038', '\U00011045'),
- ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
- ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'),
- ('\U000110b7', '\U000110b8'), ('\U000110d0', '\U000110e8'),
- ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'),
- ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
- ('\U0001112d', '\U00011132'), ('\U00011180', '\U00011181'),
- ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'),
- ('\U000111b3', '\U000111b5'), ('\U000111b6', '\U000111be'),
- ('\U000111bf', '\U000111bf'), ('\U000111c1', '\U000111c4'),
- ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'),
- ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'),
- ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
- ('\U00012000', '\U0001236e'), ('\U00012400', '\U00012462'),
- ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'),
- ('\U00016f51', '\U00016f7e'), ('\U00016f93', '\U00016f9f'),
- ('\U0001b000', '\U0001b001'), ('\U0001d400', '\U0001d454'),
- ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d505'), ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
- ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
- ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'),
- ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'),
- ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
- ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'),
- ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'),
- ('\U0001d7c4', '\U0001d7cb'), ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'),
- ('\U0002b740', '\U0002b81d'), ('\U0002f800', '\U0002fa1d')
- ];
-
- pub fn Alphabetic(c: char) -> bool {
- bsearch_range_table(c, Alphabetic_table)
- }
-
- static Lowercase_table : &'static [(char,char)] = &[
- ('\x61', '\x7a'), ('\xaa', '\xaa'),
- ('\xb5', '\xb5'), ('\xba', '\xba'),
- ('\xdf', '\xf6'), ('\xf8', '\xff'),
- ('\u0101', '\u0101'), ('\u0103', '\u0103'),
- ('\u0105', '\u0105'), ('\u0107', '\u0107'),
- ('\u0109', '\u0109'), ('\u010b', '\u010b'),
- ('\u010d', '\u010d'), ('\u010f', '\u010f'),
- ('\u0111', '\u0111'), ('\u0113', '\u0113'),
- ('\u0115', '\u0115'), ('\u0117', '\u0117'),
- ('\u0119', '\u0119'), ('\u011b', '\u011b'),
- ('\u011d', '\u011d'), ('\u011f', '\u011f'),
- ('\u0121', '\u0121'), ('\u0123', '\u0123'),
- ('\u0125', '\u0125'), ('\u0127', '\u0127'),
- ('\u0129', '\u0129'), ('\u012b', '\u012b'),
- ('\u012d', '\u012d'), ('\u012f', '\u012f'),
- ('\u0131', '\u0131'), ('\u0133', '\u0133'),
- ('\u0135', '\u0135'), ('\u0137', '\u0138'),
- ('\u013a', '\u013a'), ('\u013c', '\u013c'),
- ('\u013e', '\u013e'), ('\u0140', '\u0140'),
- ('\u0142', '\u0142'), ('\u0144', '\u0144'),
- ('\u0146', '\u0146'), ('\u0148', '\u0149'),
- ('\u014b', '\u014b'), ('\u014d', '\u014d'),
- ('\u014f', '\u014f'), ('\u0151', '\u0151'),
- ('\u0153', '\u0153'), ('\u0155', '\u0155'),
- ('\u0157', '\u0157'), ('\u0159', '\u0159'),
- ('\u015b', '\u015b'), ('\u015d', '\u015d'),
- ('\u015f', '\u015f'), ('\u0161', '\u0161'),
- ('\u0163', '\u0163'), ('\u0165', '\u0165'),
- ('\u0167', '\u0167'), ('\u0169', '\u0169'),
- ('\u016b', '\u016b'), ('\u016d', '\u016d'),
- ('\u016f', '\u016f'), ('\u0171', '\u0171'),
- ('\u0173', '\u0173'), ('\u0175', '\u0175'),
- ('\u0177', '\u0177'), ('\u017a', '\u017a'),
- ('\u017c', '\u017c'), ('\u017e', '\u0180'),
- ('\u0183', '\u0183'), ('\u0185', '\u0185'),
- ('\u0188', '\u0188'), ('\u018c', '\u018d'),
- ('\u0192', '\u0192'), ('\u0195', '\u0195'),
- ('\u0199', '\u019b'), ('\u019e', '\u019e'),
- ('\u01a1', '\u01a1'), ('\u01a3', '\u01a3'),
- ('\u01a5', '\u01a5'), ('\u01a8', '\u01a8'),
- ('\u01aa', '\u01ab'), ('\u01ad', '\u01ad'),
- ('\u01b0', '\u01b0'), ('\u01b4', '\u01b4'),
- ('\u01b6', '\u01b6'), ('\u01b9', '\u01ba'),
- ('\u01bd', '\u01bf'), ('\u01c6', '\u01c6'),
- ('\u01c9', '\u01c9'), ('\u01cc', '\u01cc'),
- ('\u01ce', '\u01ce'), ('\u01d0', '\u01d0'),
- ('\u01d2', '\u01d2'), ('\u01d4', '\u01d4'),
- ('\u01d6', '\u01d6'), ('\u01d8', '\u01d8'),
- ('\u01da', '\u01da'), ('\u01dc', '\u01dd'),
- ('\u01df', '\u01df'), ('\u01e1', '\u01e1'),
- ('\u01e3', '\u01e3'), ('\u01e5', '\u01e5'),
- ('\u01e7', '\u01e7'), ('\u01e9', '\u01e9'),
- ('\u01eb', '\u01eb'), ('\u01ed', '\u01ed'),
- ('\u01ef', '\u01f0'), ('\u01f3', '\u01f3'),
- ('\u01f5', '\u01f5'), ('\u01f9', '\u01f9'),
- ('\u01fb', '\u01fb'), ('\u01fd', '\u01fd'),
- ('\u01ff', '\u01ff'), ('\u0201', '\u0201'),
- ('\u0203', '\u0203'), ('\u0205', '\u0205'),
- ('\u0207', '\u0207'), ('\u0209', '\u0209'),
- ('\u020b', '\u020b'), ('\u020d', '\u020d'),
- ('\u020f', '\u020f'), ('\u0211', '\u0211'),
- ('\u0213', '\u0213'), ('\u0215', '\u0215'),
- ('\u0217', '\u0217'), ('\u0219', '\u0219'),
- ('\u021b', '\u021b'), ('\u021d', '\u021d'),
- ('\u021f', '\u021f'), ('\u0221', '\u0221'),
- ('\u0223', '\u0223'), ('\u0225', '\u0225'),
- ('\u0227', '\u0227'), ('\u0229', '\u0229'),
- ('\u022b', '\u022b'), ('\u022d', '\u022d'),
- ('\u022f', '\u022f'), ('\u0231', '\u0231'),
- ('\u0233', '\u0239'), ('\u023c', '\u023c'),
- ('\u023f', '\u0240'), ('\u0242', '\u0242'),
- ('\u0247', '\u0247'), ('\u0249', '\u0249'),
- ('\u024b', '\u024b'), ('\u024d', '\u024d'),
- ('\u024f', '\u0293'), ('\u0295', '\u02af'),
- ('\u02b0', '\u02b8'), ('\u02c0', '\u02c1'),
- ('\u02e0', '\u02e4'), ('\u0345', '\u0345'),
- ('\u0371', '\u0371'), ('\u0373', '\u0373'),
- ('\u0377', '\u0377'), ('\u037a', '\u037a'),
- ('\u037b', '\u037d'), ('\u0390', '\u0390'),
- ('\u03ac', '\u03ce'), ('\u03d0', '\u03d1'),
- ('\u03d5', '\u03d7'), ('\u03d9', '\u03d9'),
- ('\u03db', '\u03db'), ('\u03dd', '\u03dd'),
- ('\u03df', '\u03df'), ('\u03e1', '\u03e1'),
- ('\u03e3', '\u03e3'), ('\u03e5', '\u03e5'),
- ('\u03e7', '\u03e7'), ('\u03e9', '\u03e9'),
- ('\u03eb', '\u03eb'), ('\u03ed', '\u03ed'),
- ('\u03ef', '\u03f3'), ('\u03f5', '\u03f5'),
- ('\u03f8', '\u03f8'), ('\u03fb', '\u03fc'),
- ('\u0430', '\u045f'), ('\u0461', '\u0461'),
- ('\u0463', '\u0463'), ('\u0465', '\u0465'),
- ('\u0467', '\u0467'), ('\u0469', '\u0469'),
- ('\u046b', '\u046b'), ('\u046d', '\u046d'),
- ('\u046f', '\u046f'), ('\u0471', '\u0471'),
- ('\u0473', '\u0473'), ('\u0475', '\u0475'),
- ('\u0477', '\u0477'), ('\u0479', '\u0479'),
- ('\u047b', '\u047b'), ('\u047d', '\u047d'),
- ('\u047f', '\u047f'), ('\u0481', '\u0481'),
- ('\u048b', '\u048b'), ('\u048d', '\u048d'),
- ('\u048f', '\u048f'), ('\u0491', '\u0491'),
- ('\u0493', '\u0493'), ('\u0495', '\u0495'),
- ('\u0497', '\u0497'), ('\u0499', '\u0499'),
- ('\u049b', '\u049b'), ('\u049d', '\u049d'),
- ('\u049f', '\u049f'), ('\u04a1', '\u04a1'),
- ('\u04a3', '\u04a3'), ('\u04a5', '\u04a5'),
- ('\u04a7', '\u04a7'), ('\u04a9', '\u04a9'),
- ('\u04ab', '\u04ab'), ('\u04ad', '\u04ad'),
- ('\u04af', '\u04af'), ('\u04b1', '\u04b1'),
- ('\u04b3', '\u04b3'), ('\u04b5', '\u04b5'),
- ('\u04b7', '\u04b7'), ('\u04b9', '\u04b9'),
- ('\u04bb', '\u04bb'), ('\u04bd', '\u04bd'),
- ('\u04bf', '\u04bf'), ('\u04c2', '\u04c2'),
- ('\u04c4', '\u04c4'), ('\u04c6', '\u04c6'),
- ('\u04c8', '\u04c8'), ('\u04ca', '\u04ca'),
- ('\u04cc', '\u04cc'), ('\u04ce', '\u04cf'),
- ('\u04d1', '\u04d1'), ('\u04d3', '\u04d3'),
- ('\u04d5', '\u04d5'), ('\u04d7', '\u04d7'),
- ('\u04d9', '\u04d9'), ('\u04db', '\u04db'),
- ('\u04dd', '\u04dd'), ('\u04df', '\u04df'),
- ('\u04e1', '\u04e1'), ('\u04e3', '\u04e3'),
- ('\u04e5', '\u04e5'), ('\u04e7', '\u04e7'),
- ('\u04e9', '\u04e9'), ('\u04eb', '\u04eb'),
- ('\u04ed', '\u04ed'), ('\u04ef', '\u04ef'),
- ('\u04f1', '\u04f1'), ('\u04f3', '\u04f3'),
- ('\u04f5', '\u04f5'), ('\u04f7', '\u04f7'),
- ('\u04f9', '\u04f9'), ('\u04fb', '\u04fb'),
- ('\u04fd', '\u04fd'), ('\u04ff', '\u04ff'),
- ('\u0501', '\u0501'), ('\u0503', '\u0503'),
- ('\u0505', '\u0505'), ('\u0507', '\u0507'),
- ('\u0509', '\u0509'), ('\u050b', '\u050b'),
- ('\u050d', '\u050d'), ('\u050f', '\u050f'),
- ('\u0511', '\u0511'), ('\u0513', '\u0513'),
- ('\u0515', '\u0515'), ('\u0517', '\u0517'),
- ('\u0519', '\u0519'), ('\u051b', '\u051b'),
- ('\u051d', '\u051d'), ('\u051f', '\u051f'),
- ('\u0521', '\u0521'), ('\u0523', '\u0523'),
- ('\u0525', '\u0525'), ('\u0527', '\u0527'),
- ('\u0561', '\u0587'), ('\u1d00', '\u1d2b'),
- ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
- ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
- ('\u1d9b', '\u1dbf'), ('\u1e01', '\u1e01'),
- ('\u1e03', '\u1e03'), ('\u1e05', '\u1e05'),
- ('\u1e07', '\u1e07'), ('\u1e09', '\u1e09'),
- ('\u1e0b', '\u1e0b'), ('\u1e0d', '\u1e0d'),
- ('\u1e0f', '\u1e0f'), ('\u1e11', '\u1e11'),
- ('\u1e13', '\u1e13'), ('\u1e15', '\u1e15'),
- ('\u1e17', '\u1e17'), ('\u1e19', '\u1e19'),
- ('\u1e1b', '\u1e1b'), ('\u1e1d', '\u1e1d'),
- ('\u1e1f', '\u1e1f'), ('\u1e21', '\u1e21'),
- ('\u1e23', '\u1e23'), ('\u1e25', '\u1e25'),
- ('\u1e27', '\u1e27'), ('\u1e29', '\u1e29'),
- ('\u1e2b', '\u1e2b'), ('\u1e2d', '\u1e2d'),
- ('\u1e2f', '\u1e2f'), ('\u1e31', '\u1e31'),
- ('\u1e33', '\u1e33'), ('\u1e35', '\u1e35'),
- ('\u1e37', '\u1e37'), ('\u1e39', '\u1e39'),
- ('\u1e3b', '\u1e3b'), ('\u1e3d', '\u1e3d'),
- ('\u1e3f', '\u1e3f'), ('\u1e41', '\u1e41'),
- ('\u1e43', '\u1e43'), ('\u1e45', '\u1e45'),
- ('\u1e47', '\u1e47'), ('\u1e49', '\u1e49'),
- ('\u1e4b', '\u1e4b'), ('\u1e4d', '\u1e4d'),
- ('\u1e4f', '\u1e4f'), ('\u1e51', '\u1e51'),
- ('\u1e53', '\u1e53'), ('\u1e55', '\u1e55'),
- ('\u1e57', '\u1e57'), ('\u1e59', '\u1e59'),
- ('\u1e5b', '\u1e5b'), ('\u1e5d', '\u1e5d'),
- ('\u1e5f', '\u1e5f'), ('\u1e61', '\u1e61'),
- ('\u1e63', '\u1e63'), ('\u1e65', '\u1e65'),
- ('\u1e67', '\u1e67'), ('\u1e69', '\u1e69'),
- ('\u1e6b', '\u1e6b'), ('\u1e6d', '\u1e6d'),
- ('\u1e6f', '\u1e6f'), ('\u1e71', '\u1e71'),
- ('\u1e73', '\u1e73'), ('\u1e75', '\u1e75'),
- ('\u1e77', '\u1e77'), ('\u1e79', '\u1e79'),
- ('\u1e7b', '\u1e7b'), ('\u1e7d', '\u1e7d'),
- ('\u1e7f', '\u1e7f'), ('\u1e81', '\u1e81'),
- ('\u1e83', '\u1e83'), ('\u1e85', '\u1e85'),
- ('\u1e87', '\u1e87'), ('\u1e89', '\u1e89'),
- ('\u1e8b', '\u1e8b'), ('\u1e8d', '\u1e8d'),
- ('\u1e8f', '\u1e8f'), ('\u1e91', '\u1e91'),
- ('\u1e93', '\u1e93'), ('\u1e95', '\u1e9d'),
- ('\u1e9f', '\u1e9f'), ('\u1ea1', '\u1ea1'),
- ('\u1ea3', '\u1ea3'), ('\u1ea5', '\u1ea5'),
- ('\u1ea7', '\u1ea7'), ('\u1ea9', '\u1ea9'),
- ('\u1eab', '\u1eab'), ('\u1ead', '\u1ead'),
- ('\u1eaf', '\u1eaf'), ('\u1eb1', '\u1eb1'),
- ('\u1eb3', '\u1eb3'), ('\u1eb5', '\u1eb5'),
- ('\u1eb7', '\u1eb7'), ('\u1eb9', '\u1eb9'),
- ('\u1ebb', '\u1ebb'), ('\u1ebd', '\u1ebd'),
- ('\u1ebf', '\u1ebf'), ('\u1ec1', '\u1ec1'),
- ('\u1ec3', '\u1ec3'), ('\u1ec5', '\u1ec5'),
- ('\u1ec7', '\u1ec7'), ('\u1ec9', '\u1ec9'),
- ('\u1ecb', '\u1ecb'), ('\u1ecd', '\u1ecd'),
- ('\u1ecf', '\u1ecf'), ('\u1ed1', '\u1ed1'),
- ('\u1ed3', '\u1ed3'), ('\u1ed5', '\u1ed5'),
- ('\u1ed7', '\u1ed7'), ('\u1ed9', '\u1ed9'),
- ('\u1edb', '\u1edb'), ('\u1edd', '\u1edd'),
- ('\u1edf', '\u1edf'), ('\u1ee1', '\u1ee1'),
- ('\u1ee3', '\u1ee3'), ('\u1ee5', '\u1ee5'),
- ('\u1ee7', '\u1ee7'), ('\u1ee9', '\u1ee9'),
- ('\u1eeb', '\u1eeb'), ('\u1eed', '\u1eed'),
- ('\u1eef', '\u1eef'), ('\u1ef1', '\u1ef1'),
- ('\u1ef3', '\u1ef3'), ('\u1ef5', '\u1ef5'),
- ('\u1ef7', '\u1ef7'), ('\u1ef9', '\u1ef9'),
- ('\u1efb', '\u1efb'), ('\u1efd', '\u1efd'),
- ('\u1eff', '\u1f07'), ('\u1f10', '\u1f15'),
- ('\u1f20', '\u1f27'), ('\u1f30', '\u1f37'),
- ('\u1f40', '\u1f45'), ('\u1f50', '\u1f57'),
- ('\u1f60', '\u1f67'), ('\u1f70', '\u1f7d'),
- ('\u1f80', '\u1f87'), ('\u1f90', '\u1f97'),
- ('\u1fa0', '\u1fa7'), ('\u1fb0', '\u1fb4'),
- ('\u1fb6', '\u1fb7'), ('\u1fbe', '\u1fbe'),
- ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fc7'),
- ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fd7'),
- ('\u1fe0', '\u1fe7'), ('\u1ff2', '\u1ff4'),
- ('\u1ff6', '\u1ff7'), ('\u2071', '\u2071'),
- ('\u207f', '\u207f'), ('\u2090', '\u209c'),
- ('\u210a', '\u210a'), ('\u210e', '\u210f'),
- ('\u2113', '\u2113'), ('\u212f', '\u212f'),
- ('\u2134', '\u2134'), ('\u2139', '\u2139'),
- ('\u213c', '\u213d'), ('\u2146', '\u2149'),
- ('\u214e', '\u214e'), ('\u2170', '\u217f'),
- ('\u2184', '\u2184'), ('\u24d0', '\u24e9'),
- ('\u2c30', '\u2c5e'), ('\u2c61', '\u2c61'),
- ('\u2c65', '\u2c66'), ('\u2c68', '\u2c68'),
- ('\u2c6a', '\u2c6a'), ('\u2c6c', '\u2c6c'),
- ('\u2c71', '\u2c71'), ('\u2c73', '\u2c74'),
- ('\u2c76', '\u2c7b'), ('\u2c7c', '\u2c7d'),
- ('\u2c81', '\u2c81'), ('\u2c83', '\u2c83'),
- ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'),
- ('\u2c89', '\u2c89'), ('\u2c8b', '\u2c8b'),
- ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'),
- ('\u2c91', '\u2c91'), ('\u2c93', '\u2c93'),
- ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'),
- ('\u2c99', '\u2c99'), ('\u2c9b', '\u2c9b'),
- ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'),
- ('\u2ca1', '\u2ca1'), ('\u2ca3', '\u2ca3'),
- ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'),
- ('\u2ca9', '\u2ca9'), ('\u2cab', '\u2cab'),
- ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'),
- ('\u2cb1', '\u2cb1'), ('\u2cb3', '\u2cb3'),
- ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'),
- ('\u2cb9', '\u2cb9'), ('\u2cbb', '\u2cbb'),
- ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'),
- ('\u2cc1', '\u2cc1'), ('\u2cc3', '\u2cc3'),
- ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'),
- ('\u2cc9', '\u2cc9'), ('\u2ccb', '\u2ccb'),
- ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'),
- ('\u2cd1', '\u2cd1'), ('\u2cd3', '\u2cd3'),
- ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'),
- ('\u2cd9', '\u2cd9'), ('\u2cdb', '\u2cdb'),
- ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'),
- ('\u2ce1', '\u2ce1'), ('\u2ce3', '\u2ce4'),
- ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'),
- ('\u2cf3', '\u2cf3'), ('\u2d00', '\u2d25'),
- ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
- ('\ua641', '\ua641'), ('\ua643', '\ua643'),
- ('\ua645', '\ua645'), ('\ua647', '\ua647'),
- ('\ua649', '\ua649'), ('\ua64b', '\ua64b'),
- ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'),
- ('\ua651', '\ua651'), ('\ua653', '\ua653'),
- ('\ua655', '\ua655'), ('\ua657', '\ua657'),
- ('\ua659', '\ua659'), ('\ua65b', '\ua65b'),
- ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'),
- ('\ua661', '\ua661'), ('\ua663', '\ua663'),
- ('\ua665', '\ua665'), ('\ua667', '\ua667'),
- ('\ua669', '\ua669'), ('\ua66b', '\ua66b'),
- ('\ua66d', '\ua66d'), ('\ua681', '\ua681'),
- ('\ua683', '\ua683'), ('\ua685', '\ua685'),
- ('\ua687', '\ua687'), ('\ua689', '\ua689'),
- ('\ua68b', '\ua68b'), ('\ua68d', '\ua68d'),
- ('\ua68f', '\ua68f'), ('\ua691', '\ua691'),
- ('\ua693', '\ua693'), ('\ua695', '\ua695'),
- ('\ua697', '\ua697'), ('\ua723', '\ua723'),
- ('\ua725', '\ua725'), ('\ua727', '\ua727'),
- ('\ua729', '\ua729'), ('\ua72b', '\ua72b'),
- ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'),
- ('\ua733', '\ua733'), ('\ua735', '\ua735'),
- ('\ua737', '\ua737'), ('\ua739', '\ua739'),
- ('\ua73b', '\ua73b'), ('\ua73d', '\ua73d'),
- ('\ua73f', '\ua73f'), ('\ua741', '\ua741'),
- ('\ua743', '\ua743'), ('\ua745', '\ua745'),
- ('\ua747', '\ua747'), ('\ua749', '\ua749'),
- ('\ua74b', '\ua74b'), ('\ua74d', '\ua74d'),
- ('\ua74f', '\ua74f'), ('\ua751', '\ua751'),
- ('\ua753', '\ua753'), ('\ua755', '\ua755'),
- ('\ua757', '\ua757'), ('\ua759', '\ua759'),
- ('\ua75b', '\ua75b'), ('\ua75d', '\ua75d'),
- ('\ua75f', '\ua75f'), ('\ua761', '\ua761'),
- ('\ua763', '\ua763'), ('\ua765', '\ua765'),
- ('\ua767', '\ua767'), ('\ua769', '\ua769'),
- ('\ua76b', '\ua76b'), ('\ua76d', '\ua76d'),
- ('\ua76f', '\ua76f'), ('\ua770', '\ua770'),
- ('\ua771', '\ua778'), ('\ua77a', '\ua77a'),
- ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'),
- ('\ua781', '\ua781'), ('\ua783', '\ua783'),
- ('\ua785', '\ua785'), ('\ua787', '\ua787'),
- ('\ua78c', '\ua78c'), ('\ua78e', '\ua78e'),
- ('\ua791', '\ua791'), ('\ua793', '\ua793'),
- ('\ua7a1', '\ua7a1'), ('\ua7a3', '\ua7a3'),
- ('\ua7a5', '\ua7a5'), ('\ua7a7', '\ua7a7'),
- ('\ua7a9', '\ua7a9'), ('\ua7f8', '\ua7f9'),
- ('\ua7fa', '\ua7fa'), ('\ufb00', '\ufb06'),
- ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'),
- ('\U00010428', '\U0001044f'), ('\U0001d41a', '\U0001d433'),
- ('\U0001d44e', '\U0001d454'), ('\U0001d456', '\U0001d467'),
- ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d4cf'), ('\U0001d4ea', '\U0001d503'),
- ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'),
- ('\U0001d586', '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'),
- ('\U0001d5ee', '\U0001d607'), ('\U0001d622', '\U0001d63b'),
- ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d71b'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d78f'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7c9'),
- ('\U0001d7cb', '\U0001d7cb')
- ];
-
- pub fn Lowercase(c: char) -> bool {
- bsearch_range_table(c, Lowercase_table)
- }
-
- static Uppercase_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\xc0', '\xd6'),
- ('\xd8', '\xde'), ('\u0100', '\u0100'),
- ('\u0102', '\u0102'), ('\u0104', '\u0104'),
- ('\u0106', '\u0106'), ('\u0108', '\u0108'),
- ('\u010a', '\u010a'), ('\u010c', '\u010c'),
- ('\u010e', '\u010e'), ('\u0110', '\u0110'),
- ('\u0112', '\u0112'), ('\u0114', '\u0114'),
- ('\u0116', '\u0116'), ('\u0118', '\u0118'),
- ('\u011a', '\u011a'), ('\u011c', '\u011c'),
- ('\u011e', '\u011e'), ('\u0120', '\u0120'),
- ('\u0122', '\u0122'), ('\u0124', '\u0124'),
- ('\u0126', '\u0126'), ('\u0128', '\u0128'),
- ('\u012a', '\u012a'), ('\u012c', '\u012c'),
- ('\u012e', '\u012e'), ('\u0130', '\u0130'),
- ('\u0132', '\u0132'), ('\u0134', '\u0134'),
- ('\u0136', '\u0136'), ('\u0139', '\u0139'),
- ('\u013b', '\u013b'), ('\u013d', '\u013d'),
- ('\u013f', '\u013f'), ('\u0141', '\u0141'),
- ('\u0143', '\u0143'), ('\u0145', '\u0145'),
- ('\u0147', '\u0147'), ('\u014a', '\u014a'),
- ('\u014c', '\u014c'), ('\u014e', '\u014e'),
- ('\u0150', '\u0150'), ('\u0152', '\u0152'),
- ('\u0154', '\u0154'), ('\u0156', '\u0156'),
- ('\u0158', '\u0158'), ('\u015a', '\u015a'),
- ('\u015c', '\u015c'), ('\u015e', '\u015e'),
- ('\u0160', '\u0160'), ('\u0162', '\u0162'),
- ('\u0164', '\u0164'), ('\u0166', '\u0166'),
- ('\u0168', '\u0168'), ('\u016a', '\u016a'),
- ('\u016c', '\u016c'), ('\u016e', '\u016e'),
- ('\u0170', '\u0170'), ('\u0172', '\u0172'),
- ('\u0174', '\u0174'), ('\u0176', '\u0176'),
- ('\u0178', '\u0179'), ('\u017b', '\u017b'),
- ('\u017d', '\u017d'), ('\u0181', '\u0182'),
- ('\u0184', '\u0184'), ('\u0186', '\u0187'),
- ('\u0189', '\u018b'), ('\u018e', '\u0191'),
- ('\u0193', '\u0194'), ('\u0196', '\u0198'),
- ('\u019c', '\u019d'), ('\u019f', '\u01a0'),
- ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'),
- ('\u01a6', '\u01a7'), ('\u01a9', '\u01a9'),
- ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'),
- ('\u01b1', '\u01b3'), ('\u01b5', '\u01b5'),
- ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'),
- ('\u01c4', '\u01c4'), ('\u01c7', '\u01c7'),
- ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'),
- ('\u01cf', '\u01cf'), ('\u01d1', '\u01d1'),
- ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'),
- ('\u01d7', '\u01d7'), ('\u01d9', '\u01d9'),
- ('\u01db', '\u01db'), ('\u01de', '\u01de'),
- ('\u01e0', '\u01e0'), ('\u01e2', '\u01e2'),
- ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'),
- ('\u01e8', '\u01e8'), ('\u01ea', '\u01ea'),
- ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'),
- ('\u01f1', '\u01f1'), ('\u01f4', '\u01f4'),
- ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'),
- ('\u01fc', '\u01fc'), ('\u01fe', '\u01fe'),
- ('\u0200', '\u0200'), ('\u0202', '\u0202'),
- ('\u0204', '\u0204'), ('\u0206', '\u0206'),
- ('\u0208', '\u0208'), ('\u020a', '\u020a'),
- ('\u020c', '\u020c'), ('\u020e', '\u020e'),
- ('\u0210', '\u0210'), ('\u0212', '\u0212'),
- ('\u0214', '\u0214'), ('\u0216', '\u0216'),
- ('\u0218', '\u0218'), ('\u021a', '\u021a'),
- ('\u021c', '\u021c'), ('\u021e', '\u021e'),
- ('\u0220', '\u0220'), ('\u0222', '\u0222'),
- ('\u0224', '\u0224'), ('\u0226', '\u0226'),
- ('\u0228', '\u0228'), ('\u022a', '\u022a'),
- ('\u022c', '\u022c'), ('\u022e', '\u022e'),
- ('\u0230', '\u0230'), ('\u0232', '\u0232'),
- ('\u023a', '\u023b'), ('\u023d', '\u023e'),
- ('\u0241', '\u0241'), ('\u0243', '\u0246'),
- ('\u0248', '\u0248'), ('\u024a', '\u024a'),
- ('\u024c', '\u024c'), ('\u024e', '\u024e'),
- ('\u0370', '\u0370'), ('\u0372', '\u0372'),
- ('\u0376', '\u0376'), ('\u0386', '\u0386'),
- ('\u0388', '\u038a'), ('\u038c', '\u038c'),
- ('\u038e', '\u038f'), ('\u0391', '\u03a1'),
- ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'),
- ('\u03d2', '\u03d4'), ('\u03d8', '\u03d8'),
- ('\u03da', '\u03da'), ('\u03dc', '\u03dc'),
- ('\u03de', '\u03de'), ('\u03e0', '\u03e0'),
- ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'),
- ('\u03e6', '\u03e6'), ('\u03e8', '\u03e8'),
- ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'),
- ('\u03ee', '\u03ee'), ('\u03f4', '\u03f4'),
- ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'),
- ('\u03fd', '\u042f'), ('\u0460', '\u0460'),
- ('\u0462', '\u0462'), ('\u0464', '\u0464'),
- ('\u0466', '\u0466'), ('\u0468', '\u0468'),
- ('\u046a', '\u046a'), ('\u046c', '\u046c'),
- ('\u046e', '\u046e'), ('\u0470', '\u0470'),
- ('\u0472', '\u0472'), ('\u0474', '\u0474'),
- ('\u0476', '\u0476'), ('\u0478', '\u0478'),
- ('\u047a', '\u047a'), ('\u047c', '\u047c'),
- ('\u047e', '\u047e'), ('\u0480', '\u0480'),
- ('\u048a', '\u048a'), ('\u048c', '\u048c'),
- ('\u048e', '\u048e'), ('\u0490', '\u0490'),
- ('\u0492', '\u0492'), ('\u0494', '\u0494'),
- ('\u0496', '\u0496'), ('\u0498', '\u0498'),
- ('\u049a', '\u049a'), ('\u049c', '\u049c'),
- ('\u049e', '\u049e'), ('\u04a0', '\u04a0'),
- ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'),
- ('\u04a6', '\u04a6'), ('\u04a8', '\u04a8'),
- ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'),
- ('\u04ae', '\u04ae'), ('\u04b0', '\u04b0'),
- ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'),
- ('\u04b6', '\u04b6'), ('\u04b8', '\u04b8'),
- ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'),
- ('\u04be', '\u04be'), ('\u04c0', '\u04c1'),
- ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'),
- ('\u04c7', '\u04c7'), ('\u04c9', '\u04c9'),
- ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'),
- ('\u04d0', '\u04d0'), ('\u04d2', '\u04d2'),
- ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'),
- ('\u04d8', '\u04d8'), ('\u04da', '\u04da'),
- ('\u04dc', '\u04dc'), ('\u04de', '\u04de'),
- ('\u04e0', '\u04e0'), ('\u04e2', '\u04e2'),
- ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'),
- ('\u04e8', '\u04e8'), ('\u04ea', '\u04ea'),
- ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'),
- ('\u04f0', '\u04f0'), ('\u04f2', '\u04f2'),
- ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'),
- ('\u04f8', '\u04f8'), ('\u04fa', '\u04fa'),
- ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'),
- ('\u0500', '\u0500'), ('\u0502', '\u0502'),
- ('\u0504', '\u0504'), ('\u0506', '\u0506'),
- ('\u0508', '\u0508'), ('\u050a', '\u050a'),
- ('\u050c', '\u050c'), ('\u050e', '\u050e'),
- ('\u0510', '\u0510'), ('\u0512', '\u0512'),
- ('\u0514', '\u0514'), ('\u0516', '\u0516'),
- ('\u0518', '\u0518'), ('\u051a', '\u051a'),
- ('\u051c', '\u051c'), ('\u051e', '\u051e'),
- ('\u0520', '\u0520'), ('\u0522', '\u0522'),
- ('\u0524', '\u0524'), ('\u0526', '\u0526'),
- ('\u0531', '\u0556'), ('\u10a0', '\u10c5'),
- ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
- ('\u1e00', '\u1e00'), ('\u1e02', '\u1e02'),
- ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'),
- ('\u1e08', '\u1e08'), ('\u1e0a', '\u1e0a'),
- ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'),
- ('\u1e10', '\u1e10'), ('\u1e12', '\u1e12'),
- ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'),
- ('\u1e18', '\u1e18'), ('\u1e1a', '\u1e1a'),
- ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'),
- ('\u1e20', '\u1e20'), ('\u1e22', '\u1e22'),
- ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'),
- ('\u1e28', '\u1e28'), ('\u1e2a', '\u1e2a'),
- ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'),
- ('\u1e30', '\u1e30'), ('\u1e32', '\u1e32'),
- ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'),
- ('\u1e38', '\u1e38'), ('\u1e3a', '\u1e3a'),
- ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'),
- ('\u1e40', '\u1e40'), ('\u1e42', '\u1e42'),
- ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'),
- ('\u1e48', '\u1e48'), ('\u1e4a', '\u1e4a'),
- ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'),
- ('\u1e50', '\u1e50'), ('\u1e52', '\u1e52'),
- ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'),
- ('\u1e58', '\u1e58'), ('\u1e5a', '\u1e5a'),
- ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'),
- ('\u1e60', '\u1e60'), ('\u1e62', '\u1e62'),
- ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'),
- ('\u1e68', '\u1e68'), ('\u1e6a', '\u1e6a'),
- ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'),
- ('\u1e70', '\u1e70'), ('\u1e72', '\u1e72'),
- ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'),
- ('\u1e78', '\u1e78'), ('\u1e7a', '\u1e7a'),
- ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'),
- ('\u1e80', '\u1e80'), ('\u1e82', '\u1e82'),
- ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'),
- ('\u1e88', '\u1e88'), ('\u1e8a', '\u1e8a'),
- ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'),
- ('\u1e90', '\u1e90'), ('\u1e92', '\u1e92'),
- ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'),
- ('\u1ea0', '\u1ea0'), ('\u1ea2', '\u1ea2'),
- ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'),
- ('\u1ea8', '\u1ea8'), ('\u1eaa', '\u1eaa'),
- ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'),
- ('\u1eb0', '\u1eb0'), ('\u1eb2', '\u1eb2'),
- ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'),
- ('\u1eb8', '\u1eb8'), ('\u1eba', '\u1eba'),
- ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'),
- ('\u1ec0', '\u1ec0'), ('\u1ec2', '\u1ec2'),
- ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'),
- ('\u1ec8', '\u1ec8'), ('\u1eca', '\u1eca'),
- ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'),
- ('\u1ed0', '\u1ed0'), ('\u1ed2', '\u1ed2'),
- ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'),
- ('\u1ed8', '\u1ed8'), ('\u1eda', '\u1eda'),
- ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'),
- ('\u1ee0', '\u1ee0'), ('\u1ee2', '\u1ee2'),
- ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'),
- ('\u1ee8', '\u1ee8'), ('\u1eea', '\u1eea'),
- ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'),
- ('\u1ef0', '\u1ef0'), ('\u1ef2', '\u1ef2'),
- ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'),
- ('\u1ef8', '\u1ef8'), ('\u1efa', '\u1efa'),
- ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'),
- ('\u1f08', '\u1f0f'), ('\u1f18', '\u1f1d'),
- ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'),
- ('\u1f48', '\u1f4d'), ('\u1f59', '\u1f59'),
- ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'),
- ('\u1f5f', '\u1f5f'), ('\u1f68', '\u1f6f'),
- ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'),
- ('\u1fd8', '\u1fdb'), ('\u1fe8', '\u1fec'),
- ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210b', '\u210d'),
- ('\u2110', '\u2112'), ('\u2115', '\u2115'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u2130', '\u2133'),
- ('\u213e', '\u213f'), ('\u2145', '\u2145'),
- ('\u2160', '\u216f'), ('\u2183', '\u2183'),
- ('\u24b6', '\u24cf'), ('\u2c00', '\u2c2e'),
- ('\u2c60', '\u2c60'), ('\u2c62', '\u2c64'),
- ('\u2c67', '\u2c67'), ('\u2c69', '\u2c69'),
- ('\u2c6b', '\u2c6b'), ('\u2c6d', '\u2c70'),
- ('\u2c72', '\u2c72'), ('\u2c75', '\u2c75'),
- ('\u2c7e', '\u2c80'), ('\u2c82', '\u2c82'),
- ('\u2c84', '\u2c84'), ('\u2c86', '\u2c86'),
- ('\u2c88', '\u2c88'), ('\u2c8a', '\u2c8a'),
- ('\u2c8c', '\u2c8c'), ('\u2c8e', '\u2c8e'),
- ('\u2c90', '\u2c90'), ('\u2c92', '\u2c92'),
- ('\u2c94', '\u2c94'), ('\u2c96', '\u2c96'),
- ('\u2c98', '\u2c98'), ('\u2c9a', '\u2c9a'),
- ('\u2c9c', '\u2c9c'), ('\u2c9e', '\u2c9e'),
- ('\u2ca0', '\u2ca0'), ('\u2ca2', '\u2ca2'),
- ('\u2ca4', '\u2ca4'), ('\u2ca6', '\u2ca6'),
- ('\u2ca8', '\u2ca8'), ('\u2caa', '\u2caa'),
- ('\u2cac', '\u2cac'), ('\u2cae', '\u2cae'),
- ('\u2cb0', '\u2cb0'), ('\u2cb2', '\u2cb2'),
- ('\u2cb4', '\u2cb4'), ('\u2cb6', '\u2cb6'),
- ('\u2cb8', '\u2cb8'), ('\u2cba', '\u2cba'),
- ('\u2cbc', '\u2cbc'), ('\u2cbe', '\u2cbe'),
- ('\u2cc0', '\u2cc0'), ('\u2cc2', '\u2cc2'),
- ('\u2cc4', '\u2cc4'), ('\u2cc6', '\u2cc6'),
- ('\u2cc8', '\u2cc8'), ('\u2cca', '\u2cca'),
- ('\u2ccc', '\u2ccc'), ('\u2cce', '\u2cce'),
- ('\u2cd0', '\u2cd0'), ('\u2cd2', '\u2cd2'),
- ('\u2cd4', '\u2cd4'), ('\u2cd6', '\u2cd6'),
- ('\u2cd8', '\u2cd8'), ('\u2cda', '\u2cda'),
- ('\u2cdc', '\u2cdc'), ('\u2cde', '\u2cde'),
- ('\u2ce0', '\u2ce0'), ('\u2ce2', '\u2ce2'),
- ('\u2ceb', '\u2ceb'), ('\u2ced', '\u2ced'),
- ('\u2cf2', '\u2cf2'), ('\ua640', '\ua640'),
- ('\ua642', '\ua642'), ('\ua644', '\ua644'),
- ('\ua646', '\ua646'), ('\ua648', '\ua648'),
- ('\ua64a', '\ua64a'), ('\ua64c', '\ua64c'),
- ('\ua64e', '\ua64e'), ('\ua650', '\ua650'),
- ('\ua652', '\ua652'), ('\ua654', '\ua654'),
- ('\ua656', '\ua656'), ('\ua658', '\ua658'),
- ('\ua65a', '\ua65a'), ('\ua65c', '\ua65c'),
- ('\ua65e', '\ua65e'), ('\ua660', '\ua660'),
- ('\ua662', '\ua662'), ('\ua664', '\ua664'),
- ('\ua666', '\ua666'), ('\ua668', '\ua668'),
- ('\ua66a', '\ua66a'), ('\ua66c', '\ua66c'),
- ('\ua680', '\ua680'), ('\ua682', '\ua682'),
- ('\ua684', '\ua684'), ('\ua686', '\ua686'),
- ('\ua688', '\ua688'), ('\ua68a', '\ua68a'),
- ('\ua68c', '\ua68c'), ('\ua68e', '\ua68e'),
- ('\ua690', '\ua690'), ('\ua692', '\ua692'),
- ('\ua694', '\ua694'), ('\ua696', '\ua696'),
- ('\ua722', '\ua722'), ('\ua724', '\ua724'),
- ('\ua726', '\ua726'), ('\ua728', '\ua728'),
- ('\ua72a', '\ua72a'), ('\ua72c', '\ua72c'),
- ('\ua72e', '\ua72e'), ('\ua732', '\ua732'),
- ('\ua734', '\ua734'), ('\ua736', '\ua736'),
- ('\ua738', '\ua738'), ('\ua73a', '\ua73a'),
- ('\ua73c', '\ua73c'), ('\ua73e', '\ua73e'),
- ('\ua740', '\ua740'), ('\ua742', '\ua742'),
- ('\ua744', '\ua744'), ('\ua746', '\ua746'),
- ('\ua748', '\ua748'), ('\ua74a', '\ua74a'),
- ('\ua74c', '\ua74c'), ('\ua74e', '\ua74e'),
- ('\ua750', '\ua750'), ('\ua752', '\ua752'),
- ('\ua754', '\ua754'), ('\ua756', '\ua756'),
- ('\ua758', '\ua758'), ('\ua75a', '\ua75a'),
- ('\ua75c', '\ua75c'), ('\ua75e', '\ua75e'),
- ('\ua760', '\ua760'), ('\ua762', '\ua762'),
- ('\ua764', '\ua764'), ('\ua766', '\ua766'),
- ('\ua768', '\ua768'), ('\ua76a', '\ua76a'),
- ('\ua76c', '\ua76c'), ('\ua76e', '\ua76e'),
- ('\ua779', '\ua779'), ('\ua77b', '\ua77b'),
- ('\ua77d', '\ua77e'), ('\ua780', '\ua780'),
- ('\ua782', '\ua782'), ('\ua784', '\ua784'),
- ('\ua786', '\ua786'), ('\ua78b', '\ua78b'),
- ('\ua78d', '\ua78d'), ('\ua790', '\ua790'),
- ('\ua792', '\ua792'), ('\ua7a0', '\ua7a0'),
- ('\ua7a2', '\ua7a2'), ('\ua7a4', '\ua7a4'),
- ('\ua7a6', '\ua7a6'), ('\ua7a8', '\ua7a8'),
- ('\ua7aa', '\ua7aa'), ('\uff21', '\uff3a'),
- ('\U00010400', '\U00010427'), ('\U0001d400', '\U0001d419'),
- ('\U0001d434', '\U0001d44d'), ('\U0001d468', '\U0001d481'),
- ('\U0001d49c', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b5'),
- ('\U0001d4d0', '\U0001d4e9'), ('\U0001d504', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'), ('\U0001d538', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
- ('\U0001d56c', '\U0001d585'), ('\U0001d5a0', '\U0001d5b9'),
- ('\U0001d5d4', '\U0001d5ed'), ('\U0001d608', '\U0001d621'),
- ('\U0001d63c', '\U0001d655'), ('\U0001d670', '\U0001d689'),
- ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6e2', '\U0001d6fa'),
- ('\U0001d71c', '\U0001d734'), ('\U0001d756', '\U0001d76e'),
- ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca', '\U0001d7ca')
- ];
-
- pub fn Uppercase(c: char) -> bool {
- bsearch_range_table(c, Uppercase_table)
- }
-
- static XID_Continue_table : &'static [(char,char)] = &[
- ('\x30', '\x39'), ('\x41', '\x5a'),
- ('\x5f', '\x5f'), ('\x61', '\x7a'),
- ('\xaa', '\xaa'), ('\xb5', '\xb5'),
- ('\xb7', '\xb7'), ('\xba', '\xba'),
- ('\xc0', '\xd6'), ('\xd8', '\xf6'),
- ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'),
- ('\u01bc', '\u01bf'), ('\u01c0', '\u01c3'),
- ('\u01c4', '\u0293'), ('\u0294', '\u0294'),
- ('\u0295', '\u02af'), ('\u02b0', '\u02c1'),
- ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'),
- ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
- ('\u0300', '\u036f'), ('\u0370', '\u0373'),
- ('\u0374', '\u0374'), ('\u0376', '\u0377'),
- ('\u037b', '\u037d'), ('\u0386', '\u0386'),
- ('\u0387', '\u0387'), ('\u0388', '\u038a'),
- ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
- ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'),
- ('\u0483', '\u0487'), ('\u048a', '\u0527'),
- ('\u0531', '\u0556'), ('\u0559', '\u0559'),
- ('\u0561', '\u0587'), ('\u0591', '\u05bd'),
- ('\u05bf', '\u05bf'), ('\u05c1', '\u05c2'),
- ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'),
- ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'),
- ('\u0610', '\u061a'), ('\u0620', '\u063f'),
- ('\u0640', '\u0640'), ('\u0641', '\u064a'),
- ('\u064b', '\u065f'), ('\u0660', '\u0669'),
- ('\u066e', '\u066f'), ('\u0670', '\u0670'),
- ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'),
- ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
- ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'),
- ('\u06ea', '\u06ed'), ('\u06ee', '\u06ef'),
- ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'),
- ('\u06ff', '\u06ff'), ('\u0710', '\u0710'),
- ('\u0711', '\u0711'), ('\u0712', '\u072f'),
- ('\u0730', '\u074a'), ('\u074d', '\u07a5'),
- ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'),
- ('\u07c0', '\u07c9'), ('\u07ca', '\u07ea'),
- ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'),
- ('\u07fa', '\u07fa'), ('\u0800', '\u0815'),
- ('\u0816', '\u0819'), ('\u081a', '\u081a'),
- ('\u081b', '\u0823'), ('\u0824', '\u0824'),
- ('\u0825', '\u0827'), ('\u0828', '\u0828'),
- ('\u0829', '\u082d'), ('\u0840', '\u0858'),
- ('\u0859', '\u085b'), ('\u08a0', '\u08a0'),
- ('\u08a2', '\u08ac'), ('\u08e4', '\u08fe'),
- ('\u0900', '\u0902'), ('\u0903', '\u0903'),
- ('\u0904', '\u0939'), ('\u093a', '\u093a'),
- ('\u093b', '\u093b'), ('\u093c', '\u093c'),
- ('\u093d', '\u093d'), ('\u093e', '\u0940'),
- ('\u0941', '\u0948'), ('\u0949', '\u094c'),
- ('\u094d', '\u094d'), ('\u094e', '\u094f'),
- ('\u0950', '\u0950'), ('\u0951', '\u0957'),
- ('\u0958', '\u0961'), ('\u0962', '\u0963'),
- ('\u0966', '\u096f'), ('\u0971', '\u0971'),
- ('\u0972', '\u0977'), ('\u0979', '\u097f'),
- ('\u0981', '\u0981'), ('\u0982', '\u0983'),
- ('\u0985', '\u098c'), ('\u098f', '\u0990'),
- ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
- ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
- ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'),
- ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'),
- ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'),
- ('\u09cd', '\u09cd'), ('\u09ce', '\u09ce'),
- ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
- ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'),
- ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'),
- ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'),
- ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
- ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'),
- ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
- ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'),
- ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
- ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
- ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
- ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'),
- ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
- ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'),
- ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'),
- ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'),
- ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
- ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0abc'),
- ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
- ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'),
- ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
- ('\u0acd', '\u0acd'), ('\u0ad0', '\u0ad0'),
- ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'),
- ('\u0ae6', '\u0aef'), ('\u0b01', '\u0b01'),
- ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
- ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
- ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
- ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b3c'),
- ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'),
- ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'),
- ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'),
- ('\u0b4b', '\u0b4c'), ('\u0b4d', '\u0b4d'),
- ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
- ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'),
- ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'),
- ('\u0b71', '\u0b71'), ('\u0b82', '\u0b82'),
- ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
- ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'),
- ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
- ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'),
- ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
- ('\u0bbe', '\u0bbf'), ('\u0bc0', '\u0bc0'),
- ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'),
- ('\u0bca', '\u0bcc'), ('\u0bcd', '\u0bcd'),
- ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
- ('\u0be6', '\u0bef'), ('\u0c01', '\u0c03'),
- ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'),
- ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c33'),
- ('\u0c35', '\u0c39'), ('\u0c3d', '\u0c3d'),
- ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'),
- ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'),
- ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'),
- ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'),
- ('\u0c66', '\u0c6f'), ('\u0c82', '\u0c83'),
- ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
- ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
- ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cbc'),
- ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'),
- ('\u0cbf', '\u0cbf'), ('\u0cc0', '\u0cc4'),
- ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'),
- ('\u0cca', '\u0ccb'), ('\u0ccc', '\u0ccd'),
- ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'),
- ('\u0ce0', '\u0ce1'), ('\u0ce2', '\u0ce3'),
- ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2'),
- ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'),
- ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
- ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'),
- ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
- ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'),
- ('\u0d4e', '\u0d4e'), ('\u0d57', '\u0d57'),
- ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'),
- ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
- ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'),
- ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
- ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
- ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
- ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'),
- ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'),
- ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'),
- ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'),
- ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'),
- ('\u0e47', '\u0e4e'), ('\u0e50', '\u0e59'),
- ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
- ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
- ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
- ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
- ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
- ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
- ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'),
- ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
- ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'),
- ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'),
- ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf'),
- ('\u0f00', '\u0f00'), ('\u0f18', '\u0f19'),
- ('\u0f20', '\u0f29'), ('\u0f35', '\u0f35'),
- ('\u0f37', '\u0f37'), ('\u0f39', '\u0f39'),
- ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'),
- ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'),
- ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'),
- ('\u0f86', '\u0f87'), ('\u0f88', '\u0f8c'),
- ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'),
- ('\u0fc6', '\u0fc6'), ('\u1000', '\u102a'),
- ('\u102b', '\u102c'), ('\u102d', '\u1030'),
- ('\u1031', '\u1031'), ('\u1032', '\u1037'),
- ('\u1038', '\u1038'), ('\u1039', '\u103a'),
- ('\u103b', '\u103c'), ('\u103d', '\u103e'),
- ('\u103f', '\u103f'), ('\u1040', '\u1049'),
- ('\u1050', '\u1055'), ('\u1056', '\u1057'),
- ('\u1058', '\u1059'), ('\u105a', '\u105d'),
- ('\u105e', '\u1060'), ('\u1061', '\u1061'),
- ('\u1062', '\u1064'), ('\u1065', '\u1066'),
- ('\u1067', '\u106d'), ('\u106e', '\u1070'),
- ('\u1071', '\u1074'), ('\u1075', '\u1081'),
- ('\u1082', '\u1082'), ('\u1083', '\u1084'),
- ('\u1085', '\u1086'), ('\u1087', '\u108c'),
- ('\u108d', '\u108d'), ('\u108e', '\u108e'),
- ('\u108f', '\u108f'), ('\u1090', '\u1099'),
- ('\u109a', '\u109c'), ('\u109d', '\u109d'),
- ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'),
- ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
- ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'),
- ('\u124a', '\u124d'), ('\u1250', '\u1256'),
- ('\u1258', '\u1258'), ('\u125a', '\u125d'),
- ('\u1260', '\u1288'), ('\u128a', '\u128d'),
- ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
- ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'),
- ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
- ('\u12d8', '\u1310'), ('\u1312', '\u1315'),
- ('\u1318', '\u135a'), ('\u135d', '\u135f'),
- ('\u1369', '\u1371'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
- ('\u1700', '\u170c'), ('\u170e', '\u1711'),
- ('\u1712', '\u1714'), ('\u1720', '\u1731'),
- ('\u1732', '\u1734'), ('\u1740', '\u1751'),
- ('\u1752', '\u1753'), ('\u1760', '\u176c'),
- ('\u176e', '\u1770'), ('\u1772', '\u1773'),
- ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'),
- ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'),
- ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'),
- ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'),
- ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
- ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'),
- ('\u180b', '\u180d'), ('\u1810', '\u1819'),
- ('\u1820', '\u1842'), ('\u1843', '\u1843'),
- ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
- ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'),
- ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
- ('\u1920', '\u1922'), ('\u1923', '\u1926'),
- ('\u1927', '\u1928'), ('\u1929', '\u192b'),
- ('\u1930', '\u1931'), ('\u1932', '\u1932'),
- ('\u1933', '\u1938'), ('\u1939', '\u193b'),
- ('\u1946', '\u194f'), ('\u1950', '\u196d'),
- ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
- ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'),
- ('\u19c8', '\u19c9'), ('\u19d0', '\u19d9'),
- ('\u19da', '\u19da'), ('\u1a00', '\u1a16'),
- ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
- ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'),
- ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
- ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'),
- ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'),
- ('\u1a62', '\u1a62'), ('\u1a63', '\u1a64'),
- ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'),
- ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'),
- ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'),
- ('\u1aa7', '\u1aa7'), ('\u1b00', '\u1b03'),
- ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'),
- ('\u1b34', '\u1b34'), ('\u1b35', '\u1b35'),
- ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'),
- ('\u1b3c', '\u1b3c'), ('\u1b3d', '\u1b41'),
- ('\u1b42', '\u1b42'), ('\u1b43', '\u1b44'),
- ('\u1b45', '\u1b4b'), ('\u1b50', '\u1b59'),
- ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b81'),
- ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'),
- ('\u1ba1', '\u1ba1'), ('\u1ba2', '\u1ba5'),
- ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'),
- ('\u1baa', '\u1baa'), ('\u1bab', '\u1bab'),
- ('\u1bac', '\u1bad'), ('\u1bae', '\u1baf'),
- ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1be5'),
- ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'),
- ('\u1be8', '\u1be9'), ('\u1bea', '\u1bec'),
- ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'),
- ('\u1bef', '\u1bf1'), ('\u1bf2', '\u1bf3'),
- ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'),
- ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
- ('\u1c36', '\u1c37'), ('\u1c40', '\u1c49'),
- ('\u1c4d', '\u1c4f'), ('\u1c50', '\u1c59'),
- ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'),
- ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'),
- ('\u1ce1', '\u1ce1'), ('\u1ce2', '\u1ce8'),
- ('\u1ce9', '\u1cec'), ('\u1ced', '\u1ced'),
- ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'),
- ('\u1cf4', '\u1cf4'), ('\u1cf5', '\u1cf6'),
- ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'),
- ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'),
- ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'),
- ('\u1dc0', '\u1de6'), ('\u1dfc', '\u1dff'),
- ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'),
- ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'),
- ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'),
- ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'),
- ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'),
- ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'),
- ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'),
- ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'),
- ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'),
- ('\u1ff6', '\u1ffc'), ('\u203f', '\u2040'),
- ('\u2054', '\u2054'), ('\u2071', '\u2071'),
- ('\u207f', '\u207f'), ('\u2090', '\u209c'),
- ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'),
- ('\u20e5', '\u20f0'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210a', '\u2113'),
- ('\u2115', '\u2115'), ('\u2118', '\u2118'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u212e', '\u212e'),
- ('\u212f', '\u2134'), ('\u2135', '\u2138'),
- ('\u2139', '\u2139'), ('\u213c', '\u213f'),
- ('\u2145', '\u2149'), ('\u214e', '\u214e'),
- ('\u2160', '\u2182'), ('\u2183', '\u2184'),
- ('\u2185', '\u2188'), ('\u2c00', '\u2c2e'),
- ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
- ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'),
- ('\u2ceb', '\u2cee'), ('\u2cef', '\u2cf1'),
- ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
- ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
- ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'),
- ('\u2d7f', '\u2d7f'), ('\u2d80', '\u2d96'),
- ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
- ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
- ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
- ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
- ('\u2de0', '\u2dff'), ('\u3005', '\u3005'),
- ('\u3006', '\u3006'), ('\u3007', '\u3007'),
- ('\u3021', '\u3029'), ('\u302a', '\u302d'),
- ('\u302e', '\u302f'), ('\u3031', '\u3035'),
- ('\u3038', '\u303a'), ('\u303b', '\u303b'),
- ('\u303c', '\u303c'), ('\u3041', '\u3096'),
- ('\u3099', '\u309a'), ('\u309d', '\u309e'),
- ('\u309f', '\u309f'), ('\u30a1', '\u30fa'),
- ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'),
- ('\u3105', '\u312d'), ('\u3131', '\u318e'),
- ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
- ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'),
- ('\ua000', '\ua014'), ('\ua015', '\ua015'),
- ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
- ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'),
- ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'),
- ('\ua620', '\ua629'), ('\ua62a', '\ua62b'),
- ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'),
- ('\ua66f', '\ua66f'), ('\ua674', '\ua67d'),
- ('\ua67f', '\ua67f'), ('\ua680', '\ua697'),
- ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'),
- ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'),
- ('\ua717', '\ua71f'), ('\ua722', '\ua76f'),
- ('\ua770', '\ua770'), ('\ua771', '\ua787'),
- ('\ua788', '\ua788'), ('\ua78b', '\ua78e'),
- ('\ua790', '\ua793'), ('\ua7a0', '\ua7aa'),
- ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
- ('\ua7fb', '\ua801'), ('\ua802', '\ua802'),
- ('\ua803', '\ua805'), ('\ua806', '\ua806'),
- ('\ua807', '\ua80a'), ('\ua80b', '\ua80b'),
- ('\ua80c', '\ua822'), ('\ua823', '\ua824'),
- ('\ua825', '\ua826'), ('\ua827', '\ua827'),
- ('\ua840', '\ua873'), ('\ua880', '\ua881'),
- ('\ua882', '\ua8b3'), ('\ua8b4', '\ua8c3'),
- ('\ua8c4', '\ua8c4'), ('\ua8d0', '\ua8d9'),
- ('\ua8e0', '\ua8f1'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua900', '\ua909'),
- ('\ua90a', '\ua925'), ('\ua926', '\ua92d'),
- ('\ua930', '\ua946'), ('\ua947', '\ua951'),
- ('\ua952', '\ua953'), ('\ua960', '\ua97c'),
- ('\ua980', '\ua982'), ('\ua983', '\ua983'),
- ('\ua984', '\ua9b2'), ('\ua9b3', '\ua9b3'),
- ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'),
- ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
- ('\ua9bd', '\ua9c0'), ('\ua9cf', '\ua9cf'),
- ('\ua9d0', '\ua9d9'), ('\uaa00', '\uaa28'),
- ('\uaa29', '\uaa2e'), ('\uaa2f', '\uaa30'),
- ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'),
- ('\uaa35', '\uaa36'), ('\uaa40', '\uaa42'),
- ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'),
- ('\uaa4c', '\uaa4c'), ('\uaa4d', '\uaa4d'),
- ('\uaa50', '\uaa59'), ('\uaa60', '\uaa6f'),
- ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'),
- ('\uaa80', '\uaaaf'), ('\uaab0', '\uaab0'),
- ('\uaab1', '\uaab1'), ('\uaab2', '\uaab4'),
- ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'),
- ('\uaab9', '\uaabd'), ('\uaabe', '\uaabf'),
- ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'),
- ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
- ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
- ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'),
- ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'),
- ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
- ('\uaaf6', '\uaaf6'), ('\uab01', '\uab06'),
- ('\uab09', '\uab0e'), ('\uab11', '\uab16'),
- ('\uab20', '\uab26'), ('\uab28', '\uab2e'),
- ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'),
- ('\uabe5', '\uabe5'), ('\uabe6', '\uabe7'),
- ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'),
- ('\uabec', '\uabec'), ('\uabed', '\uabed'),
- ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'),
- ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
- ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
- ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
- ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
- ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
- ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
- ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
- ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
- ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'),
- ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
- ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe26'),
- ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'),
- ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'),
- ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
- ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'),
- ('\ufe7f', '\ufefc'), ('\uff10', '\uff19'),
- ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'),
- ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
- ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
- ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
- ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
- ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
- ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
- ('\U000101fd', '\U000101fd'), ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
- ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'),
- ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
- ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'),
- ('\U000104a0', '\U000104a9'), ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'), ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'),
- ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
- ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'),
- ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
- ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
- ('\U00011003', '\U00011037'), ('\U00011038', '\U00011046'),
- ('\U00011066', '\U0001106f'), ('\U00011080', '\U00011081'),
- ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
- ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'),
- ('\U000110b7', '\U000110b8'), ('\U000110b9', '\U000110ba'),
- ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9'),
- ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'),
- ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
- ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'),
- ('\U00011180', '\U00011181'), ('\U00011182', '\U00011182'),
- ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'),
- ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'),
- ('\U000111c1', '\U000111c4'), ('\U000111d0', '\U000111d9'),
- ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'),
- ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'),
- ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
- ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'),
- ('\U000116c0', '\U000116c9'), ('\U00012000', '\U0001236e'),
- ('\U00012400', '\U00012462'), ('\U00013000', '\U0001342e'),
- ('\U00016800', '\U00016a38'), ('\U00016f00', '\U00016f44'),
- ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
- ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f'),
- ('\U0001b000', '\U0001b001'), ('\U0001d165', '\U0001d166'),
- ('\U0001d167', '\U0001d169'), ('\U0001d16d', '\U0001d172'),
- ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
- ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'),
- ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
- ('\U0001d7ce', '\U0001d7ff'), ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'),
- ('\U0002b740', '\U0002b81d'), ('\U0002f800', '\U0002fa1d'),
- ('\U000e0100', '\U000e01ef')
- ];
-
- pub fn XID_Continue(c: char) -> bool {
- bsearch_range_table(c, XID_Continue_table)
- }
-
- static XID_Start_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\x61', '\x7a'),
- ('\xaa', '\xaa'), ('\xb5', '\xb5'),
- ('\xba', '\xba'), ('\xc0', '\xd6'),
- ('\xd8', '\xf6'), ('\xf8', '\u01ba'),
- ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'),
- ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'),
- ('\u0294', '\u0294'), ('\u0295', '\u02af'),
- ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
- ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
- ('\u02ee', '\u02ee'), ('\u0370', '\u0373'),
- ('\u0374', '\u0374'), ('\u0376', '\u0377'),
- ('\u037b', '\u037d'), ('\u0386', '\u0386'),
- ('\u0388', '\u038a'), ('\u038c', '\u038c'),
- ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
- ('\u03f7', '\u0481'), ('\u048a', '\u0527'),
- ('\u0531', '\u0556'), ('\u0559', '\u0559'),
- ('\u0561', '\u0587'), ('\u05d0', '\u05ea'),
- ('\u05f0', '\u05f2'), ('\u0620', '\u063f'),
- ('\u0640', '\u0640'), ('\u0641', '\u064a'),
- ('\u066e', '\u066f'), ('\u0671', '\u06d3'),
- ('\u06d5', '\u06d5'), ('\u06e5', '\u06e6'),
- ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'),
- ('\u06ff', '\u06ff'), ('\u0710', '\u0710'),
- ('\u0712', '\u072f'), ('\u074d', '\u07a5'),
- ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'),
- ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
- ('\u0800', '\u0815'), ('\u081a', '\u081a'),
- ('\u0824', '\u0824'), ('\u0828', '\u0828'),
- ('\u0840', '\u0858'), ('\u08a0', '\u08a0'),
- ('\u08a2', '\u08ac'), ('\u0904', '\u0939'),
- ('\u093d', '\u093d'), ('\u0950', '\u0950'),
- ('\u0958', '\u0961'), ('\u0971', '\u0971'),
- ('\u0972', '\u0977'), ('\u0979', '\u097f'),
- ('\u0985', '\u098c'), ('\u098f', '\u0990'),
- ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
- ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
- ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'),
- ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'),
- ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'),
- ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'),
- ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'),
- ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'),
- ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'),
- ('\u0a72', '\u0a74'), ('\u0a85', '\u0a8d'),
- ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'),
- ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
- ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'),
- ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'),
- ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'),
- ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'),
- ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'),
- ('\u0b3d', '\u0b3d'), ('\u0b5c', '\u0b5d'),
- ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'),
- ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
- ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'),
- ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
- ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'),
- ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
- ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'),
- ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'),
- ('\u0c2a', '\u0c33'), ('\u0c35', '\u0c39'),
- ('\u0c3d', '\u0c3d'), ('\u0c58', '\u0c59'),
- ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'),
- ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'),
- ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'),
- ('\u0cbd', '\u0cbd'), ('\u0cde', '\u0cde'),
- ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'),
- ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
- ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'),
- ('\u0d4e', '\u0d4e'), ('\u0d60', '\u0d61'),
- ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'),
- ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
- ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
- ('\u0e01', '\u0e30'), ('\u0e32', '\u0e32'),
- ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'),
- ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
- ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
- ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
- ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
- ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
- ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
- ('\u0eb2', '\u0eb2'), ('\u0ebd', '\u0ebd'),
- ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'),
- ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
- ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
- ('\u0f88', '\u0f8c'), ('\u1000', '\u102a'),
- ('\u103f', '\u103f'), ('\u1050', '\u1055'),
- ('\u105a', '\u105d'), ('\u1061', '\u1061'),
- ('\u1065', '\u1066'), ('\u106e', '\u1070'),
- ('\u1075', '\u1081'), ('\u108e', '\u108e'),
- ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'),
- ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
- ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'),
- ('\u124a', '\u124d'), ('\u1250', '\u1256'),
- ('\u1258', '\u1258'), ('\u125a', '\u125d'),
- ('\u1260', '\u1288'), ('\u128a', '\u128d'),
- ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
- ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'),
- ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
- ('\u12d8', '\u1310'), ('\u1312', '\u1315'),
- ('\u1318', '\u135a'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
- ('\u1700', '\u170c'), ('\u170e', '\u1711'),
- ('\u1720', '\u1731'), ('\u1740', '\u1751'),
- ('\u1760', '\u176c'), ('\u176e', '\u1770'),
- ('\u1780', '\u17b3'), ('\u17d7', '\u17d7'),
- ('\u17dc', '\u17dc'), ('\u1820', '\u1842'),
- ('\u1843', '\u1843'), ('\u1844', '\u1877'),
- ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'),
- ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
- ('\u1950', '\u196d'), ('\u1970', '\u1974'),
- ('\u1980', '\u19ab'), ('\u19c1', '\u19c7'),
- ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'),
- ('\u1aa7', '\u1aa7'), ('\u1b05', '\u1b33'),
- ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'),
- ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'),
- ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'),
- ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'),
- ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'),
- ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'),
- ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
- ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
- ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'),
- ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
- ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
- ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
- ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
- ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
- ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
- ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
- ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
- ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
- ('\u2071', '\u2071'), ('\u207f', '\u207f'),
- ('\u2090', '\u209c'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210a', '\u2113'),
- ('\u2115', '\u2115'), ('\u2118', '\u2118'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u212e', '\u212e'),
- ('\u212f', '\u2134'), ('\u2135', '\u2138'),
- ('\u2139', '\u2139'), ('\u213c', '\u213f'),
- ('\u2145', '\u2149'), ('\u214e', '\u214e'),
- ('\u2160', '\u2182'), ('\u2183', '\u2184'),
- ('\u2185', '\u2188'), ('\u2c00', '\u2c2e'),
- ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
- ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'),
- ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'),
- ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
- ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'),
- ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'),
- ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
- ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
- ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
- ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
- ('\u3005', '\u3005'), ('\u3006', '\u3006'),
- ('\u3007', '\u3007'), ('\u3021', '\u3029'),
- ('\u3031', '\u3035'), ('\u3038', '\u303a'),
- ('\u303b', '\u303b'), ('\u303c', '\u303c'),
- ('\u3041', '\u3096'), ('\u309d', '\u309e'),
- ('\u309f', '\u309f'), ('\u30a1', '\u30fa'),
- ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'),
- ('\u3105', '\u312d'), ('\u3131', '\u318e'),
- ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
- ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'),
- ('\ua000', '\ua014'), ('\ua015', '\ua015'),
- ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
- ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'),
- ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'),
- ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'),
- ('\ua66e', '\ua66e'), ('\ua67f', '\ua67f'),
- ('\ua680', '\ua697'), ('\ua6a0', '\ua6e5'),
- ('\ua6e6', '\ua6ef'), ('\ua717', '\ua71f'),
- ('\ua722', '\ua76f'), ('\ua770', '\ua770'),
- ('\ua771', '\ua787'), ('\ua788', '\ua788'),
- ('\ua78b', '\ua78e'), ('\ua790', '\ua793'),
- ('\ua7a0', '\ua7aa'), ('\ua7f8', '\ua7f9'),
- ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'),
- ('\ua803', '\ua805'), ('\ua807', '\ua80a'),
- ('\ua80c', '\ua822'), ('\ua840', '\ua873'),
- ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
- ('\ua930', '\ua946'), ('\ua960', '\ua97c'),
- ('\ua984', '\ua9b2'), ('\ua9cf', '\ua9cf'),
- ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'),
- ('\uaa44', '\uaa4b'), ('\uaa60', '\uaa6f'),
- ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
- ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'),
- ('\uaab9', '\uaabd'), ('\uaac0', '\uaac0'),
- ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
- ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
- ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'),
- ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
- ('\uab11', '\uab16'), ('\uab20', '\uab26'),
- ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'),
- ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'),
- ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'),
- ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'),
- ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'),
- ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
- ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
- ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
- ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
- ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'),
- ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
- ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'),
- ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
- ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'),
- ('\ufe7f', '\ufefc'), ('\uff21', '\uff3a'),
- ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
- ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
- ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'),
- ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'),
- ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'),
- ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
- ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'),
- ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'),
- ('\U00010140', '\U00010174'), ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
- ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'),
- ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
- ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'),
- ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
- ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'),
- ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U00010855'),
- ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'),
- ('\U00010980', '\U000109b7'), ('\U000109be', '\U000109bf'),
- ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'),
- ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'),
- ('\U00011103', '\U00011126'), ('\U00011183', '\U000111b2'),
- ('\U000111c1', '\U000111c4'), ('\U00011680', '\U000116aa'),
- ('\U00012000', '\U0001236e'), ('\U00012400', '\U00012462'),
- ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'),
- ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'),
- ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
- ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'),
- ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'),
- ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
- ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'),
- ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'),
- ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
- ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'),
- ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'),
- ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
- ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'),
- ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'),
- ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
- ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'),
- ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'),
- ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
- ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'),
- ('\U0001eeab', '\U0001eebb'), ('\U00020000', '\U0002a6d6'),
- ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
- ('\U0002f800', '\U0002fa1d')
- ];
-
- pub fn XID_Start(c: char) -> bool {
- bsearch_range_table(c, XID_Start_table)
- }
-
-}
-pub mod property {
-
- fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
- use cmp::{Equal, Less, Greater};
- use vec::ImmutableVector;
- use option::None;
- r.bsearch(|&(lo,hi)| {
- if lo <= c && c <= hi { Equal }
- else if hi < c { Less }
- else { Greater }
- }) != None
- }
-
-
- static White_Space_table : &'static [(char,char)] = &[
- ('\x09', '\x0d'), ('\x20', '\x20'),
- ('\x85', '\x85'), ('\xa0', '\xa0'),
- ('\u1680', '\u1680'), ('\u2000', '\u200a'),
- ('\u2028', '\u2028'), ('\u2029', '\u2029'),
- ('\u202f', '\u202f'), ('\u205f', '\u205f'),
- ('\u3000', '\u3000')
- ];
-
- pub fn White_Space(c: char) -> bool {
- bsearch_range_table(c, White_Space_table)
- }
-
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Functions for the unit type.
-
-#[cfg(not(test))]
-use prelude::*;
-#[cfg(not(test))]
-use num::Zero;
-
-#[cfg(not(test))]
-impl Eq for () {
- #[inline]
- fn eq(&self, _other: &()) -> bool { true }
- #[inline]
- fn ne(&self, _other: &()) -> bool { false }
-}
-
-#[cfg(not(test))]
-impl Ord for () {
- #[inline]
- fn lt(&self, _other: &()) -> bool { false }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for () {
- #[inline]
- fn cmp(&self, _other: &()) -> Ordering { Equal }
-}
-
-#[cfg(not(test))]
-impl TotalEq for () {
- #[inline]
- fn equals(&self, _other: &()) -> bool { true }
-}
-
-#[cfg(not(test))]
-impl Default for () {
- #[inline]
- fn default() -> () { () }
-}
-
-#[cfg(not(test))]
-impl Zero for () {
- #[inline]
- fn zero() -> () { () }
- #[inline]
- fn is_zero(&self) -> bool { true }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
- * Atomic types
- *
- * Basic atomic types supporting atomic operations. Each method takes an `Ordering` which
- * represents the strength of the memory barrier for that operation. These orderings are the same
- * as C++11 atomic orderings [http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync]
- *
- * All atomic types are a single word in size.
- */
-
-use unstable::intrinsics;
-use cast;
-use option::{Option,Some,None};
-use libc::c_void;
-use ops::Drop;
-use util::NonCopyable;
-
-/**
- * A simple atomic flag, that can be set and cleared. The most basic atomic type.
- */
-pub struct AtomicFlag {
- priv v: int,
- priv nocopy: NonCopyable
-}
-
-/**
- * An atomic boolean type.
- */
-pub struct AtomicBool {
- priv v: uint,
- priv nocopy: NonCopyable
-}
-
-/**
- * A signed atomic integer type, supporting basic atomic arithmetic operations
- */
-pub struct AtomicInt {
- priv v: int,
- priv nocopy: NonCopyable
-}
-
-/**
- * An unsigned atomic integer type, supporting basic atomic arithmetic operations
- */
-pub struct AtomicUint {
- priv v: uint,
- priv nocopy: NonCopyable
-}
-
-/**
- * An unsafe atomic pointer. Only supports basic atomic operations
- */
-pub struct AtomicPtr<T> {
- priv p: *mut T,
- priv nocopy: NonCopyable
-}
-
-/**
- * An owned atomic pointer. Ensures that only a single reference to the data is held at any time.
- */
-#[unsafe_no_drop_flag]
-pub struct AtomicOption<T> {
- priv p: *mut c_void
-}
-
-pub enum Ordering {
- Relaxed,
- Release,
- Acquire,
- AcqRel,
- SeqCst
-}
-
-pub static INIT_ATOMIC_FLAG : AtomicFlag = AtomicFlag { v: 0, nocopy: NonCopyable };
-pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v: 0, nocopy: NonCopyable };
-pub static INIT_ATOMIC_INT : AtomicInt = AtomicInt { v: 0, nocopy: NonCopyable };
-pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v: 0, nocopy: NonCopyable };
-
-impl AtomicFlag {
-
- pub fn new() -> AtomicFlag {
- AtomicFlag { v: 0, nocopy: NonCopyable }
- }
-
- /**
- * Clears the atomic flag
- */
- #[inline]
- pub fn clear(&mut self, order: Ordering) {
- unsafe {atomic_store(&mut self.v, 0, order)}
- }
-
- /**
- * Sets the flag if it was previously unset, returns the previous value of the
- * flag.
- */
- #[inline]
- pub fn test_and_set(&mut self, order: Ordering) -> bool {
- unsafe { atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0 }
- }
-}
-
-impl AtomicBool {
- pub fn new(v: bool) -> AtomicBool {
- AtomicBool { v: if v { 1 } else { 0 }, nocopy: NonCopyable }
- }
-
- #[inline]
- pub fn load(&self, order: Ordering) -> bool {
- unsafe { atomic_load(&self.v, order) > 0 }
- }
-
- #[inline]
- pub fn store(&mut self, val: bool, order: Ordering) {
- let val = if val { 1 } else { 0 };
-
- unsafe { atomic_store(&mut self.v, val, order); }
- }
-
- #[inline]
- pub fn swap(&mut self, val: bool, order: Ordering) -> bool {
- let val = if val { 1 } else { 0 };
-
- unsafe { atomic_swap(&mut self.v, val, order) > 0 }
- }
-
- #[inline]
- pub fn compare_and_swap(&mut self, old: bool, new: bool, order: Ordering) -> bool {
- let old = if old { 1 } else { 0 };
- let new = if new { 1 } else { 0 };
-
- unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) > 0 }
- }
-
- /// Returns the old value
- #[inline]
- pub fn fetch_and(&mut self, val: bool, order: Ordering) -> bool {
- let val = if val { 1 } else { 0 };
-
- unsafe { atomic_and(&mut self.v, val, order) > 0 }
- }
-
- /// Returns the old value
- #[inline]
- pub fn fetch_nand(&mut self, val: bool, order: Ordering) -> bool {
- let val = if val { 1 } else { 0 };
-
- unsafe { atomic_nand(&mut self.v, val, order) > 0 }
- }
-
- /// Returns the old value
- #[inline]
- pub fn fetch_or(&mut self, val: bool, order: Ordering) -> bool {
- let val = if val { 1 } else { 0 };
-
- unsafe { atomic_or(&mut self.v, val, order) > 0 }
- }
-
- /// Returns the old value
- #[inline]
- pub fn fetch_xor(&mut self, val: bool, order: Ordering) -> bool {
- let val = if val { 1 } else { 0 };
-
- unsafe { atomic_xor(&mut self.v, val, order) > 0 }
- }
-}
-
-impl AtomicInt {
- pub fn new(v: int) -> AtomicInt {
- AtomicInt { v:v, nocopy: NonCopyable }
- }
-
- #[inline]
- pub fn load(&self, order: Ordering) -> int {
- unsafe { atomic_load(&self.v, order) }
- }
-
- #[inline]
- pub fn store(&mut self, val: int, order: Ordering) {
- unsafe { atomic_store(&mut self.v, val, order); }
- }
-
- #[inline]
- pub fn swap(&mut self, val: int, order: Ordering) -> int {
- unsafe { atomic_swap(&mut self.v, val, order) }
- }
-
- #[inline]
- pub fn compare_and_swap(&mut self, old: int, new: int, order: Ordering) -> int {
- unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
- }
-
- /// Returns the old value (like __sync_fetch_and_add).
- #[inline]
- pub fn fetch_add(&mut self, val: int, order: Ordering) -> int {
- unsafe { atomic_add(&mut self.v, val, order) }
- }
-
- /// Returns the old value (like __sync_fetch_and_sub).
- #[inline]
- pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int {
- unsafe { atomic_sub(&mut self.v, val, order) }
- }
-}
-
-impl AtomicUint {
- pub fn new(v: uint) -> AtomicUint {
- AtomicUint { v:v, nocopy: NonCopyable }
- }
-
- #[inline]
- pub fn load(&self, order: Ordering) -> uint {
- unsafe { atomic_load(&self.v, order) }
- }
-
- #[inline]
- pub fn store(&mut self, val: uint, order: Ordering) {
- unsafe { atomic_store(&mut self.v, val, order); }
- }
-
- #[inline]
- pub fn swap(&mut self, val: uint, order: Ordering) -> uint {
- unsafe { atomic_swap(&mut self.v, val, order) }
- }
-
- #[inline]
- pub fn compare_and_swap(&mut self, old: uint, new: uint, order: Ordering) -> uint {
- unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
- }
-
- /// Returns the old value (like __sync_fetch_and_add).
- #[inline]
- pub fn fetch_add(&mut self, val: uint, order: Ordering) -> uint {
- unsafe { atomic_add(&mut self.v, val, order) }
- }
-
- /// Returns the old value (like __sync_fetch_and_sub)..
- #[inline]
- pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint {
- unsafe { atomic_sub(&mut self.v, val, order) }
- }
-}
-
-impl<T> AtomicPtr<T> {
- pub fn new(p: *mut T) -> AtomicPtr<T> {
- AtomicPtr { p:p, nocopy: NonCopyable }
- }
-
- #[inline]
- pub fn load(&self, order: Ordering) -> *mut T {
- unsafe { atomic_load(&self.p, order) }
- }
-
- #[inline]
- pub fn store(&mut self, ptr: *mut T, order: Ordering) {
- unsafe { atomic_store(&mut self.p, ptr, order); }
- }
-
- #[inline]
- pub fn swap(&mut self, ptr: *mut T, order: Ordering) -> *mut T {
- unsafe { atomic_swap(&mut self.p, ptr, order) }
- }
-
- #[inline]
- pub fn compare_and_swap(&mut self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
- unsafe { atomic_compare_and_swap(&mut self.p, old, new, order) }
- }
-}
-
-impl<T> AtomicOption<T> {
- pub fn new(p: ~T) -> AtomicOption<T> {
- unsafe {
- AtomicOption {
- p: cast::transmute(p)
- }
- }
- }
-
- pub fn empty() -> AtomicOption<T> {
- unsafe {
- AtomicOption {
- p: cast::transmute(0)
- }
- }
- }
-
- #[inline]
- pub fn swap(&mut self, val: ~T, order: Ordering) -> Option<~T> {
- unsafe {
- let val = cast::transmute(val);
-
- let p = atomic_swap(&mut self.p, val, order);
- let pv : &uint = cast::transmute(&p);
-
- if *pv == 0 {
- None
- } else {
- Some(cast::transmute(p))
- }
- }
- }
-
- #[inline]
- pub fn take(&mut self, order: Ordering) -> Option<~T> {
- unsafe {
- self.swap(cast::transmute(0), order)
- }
- }
-
- /// A compare-and-swap. Succeeds if the option is 'None' and returns 'None'
- /// if so. If the option was already 'Some', returns 'Some' of the rejected
- /// value.
- #[inline]
- pub fn fill(&mut self, val: ~T, order: Ordering) -> Option<~T> {
- unsafe {
- let val = cast::transmute(val);
- let expected = cast::transmute(0);
- let oldval = atomic_compare_and_swap(&mut self.p, expected, val, order);
- if oldval == expected {
- None
- } else {
- Some(cast::transmute(val))
- }
- }
- }
-
- /// Be careful: The caller must have some external method of ensuring the
- /// result does not get invalidated by another task after this returns.
- #[inline]
- pub fn is_empty(&mut self, order: Ordering) -> bool {
- unsafe { atomic_load(&self.p, order) == cast::transmute(0) }
- }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for AtomicOption<T> {
- fn drop(&mut self) {
- let _ = self.take(SeqCst);
- }
-}
-
-#[inline]
-pub unsafe fn atomic_store<T>(dst: &mut T, val: T, order:Ordering) {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- match order {
- Release => intrinsics::atomic_store_rel(dst, val),
- Relaxed => intrinsics::atomic_store_relaxed(dst, val),
- _ => intrinsics::atomic_store(dst, val)
- }
-}
-
-#[inline]
-pub unsafe fn atomic_load<T>(dst: &T, order:Ordering) -> T {
- let dst = cast::transmute(dst);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_load_acq(dst),
- Relaxed => intrinsics::atomic_load_relaxed(dst),
- _ => intrinsics::atomic_load(dst)
- })
-}
-
-#[inline]
-pub unsafe fn atomic_swap<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_xchg_acq(dst, val),
- Release => intrinsics::atomic_xchg_rel(dst, val),
- AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
- Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
- _ => intrinsics::atomic_xchg(dst, val)
- })
-}
-
-/// Returns the old value (like __sync_fetch_and_add).
-#[inline]
-pub unsafe fn atomic_add<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_xadd_acq(dst, val),
- Release => intrinsics::atomic_xadd_rel(dst, val),
- AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
- Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
- _ => intrinsics::atomic_xadd(dst, val)
- })
-}
-
-/// Returns the old value (like __sync_fetch_and_sub).
-#[inline]
-pub unsafe fn atomic_sub<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_xsub_acq(dst, val),
- Release => intrinsics::atomic_xsub_rel(dst, val),
- AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
- Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
- _ => intrinsics::atomic_xsub(dst, val)
- })
-}
-
-#[inline]
-pub unsafe fn atomic_compare_and_swap<T>(dst:&mut T, old:T, new:T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let old = cast::transmute(old);
- let new = cast::transmute(new);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_cxchg_acq(dst, old, new),
- Release => intrinsics::atomic_cxchg_rel(dst, old, new),
- AcqRel => intrinsics::atomic_cxchg_acqrel(dst, old, new),
- Relaxed => intrinsics::atomic_cxchg_relaxed(dst, old, new),
- _ => intrinsics::atomic_cxchg(dst, old, new),
- })
-}
-
-#[inline]
-pub unsafe fn atomic_and<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_and_acq(dst, val),
- Release => intrinsics::atomic_and_rel(dst, val),
- AcqRel => intrinsics::atomic_and_acqrel(dst, val),
- Relaxed => intrinsics::atomic_and_relaxed(dst, val),
- _ => intrinsics::atomic_and(dst, val)
- })
-}
-
-
-#[inline]
-pub unsafe fn atomic_nand<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_nand_acq(dst, val),
- Release => intrinsics::atomic_nand_rel(dst, val),
- AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
- Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
- _ => intrinsics::atomic_nand(dst, val)
- })
-}
-
-
-#[inline]
-pub unsafe fn atomic_or<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_or_acq(dst, val),
- Release => intrinsics::atomic_or_rel(dst, val),
- AcqRel => intrinsics::atomic_or_acqrel(dst, val),
- Relaxed => intrinsics::atomic_or_relaxed(dst, val),
- _ => intrinsics::atomic_or(dst, val)
- })
-}
-
-
-#[inline]
-pub unsafe fn atomic_xor<T>(dst: &mut T, val: T, order: Ordering) -> T {
- let dst = cast::transmute(dst);
- let val = cast::transmute(val);
-
- cast::transmute(match order {
- Acquire => intrinsics::atomic_xor_acq(dst, val),
- Release => intrinsics::atomic_xor_rel(dst, val),
- AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
- Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
- _ => intrinsics::atomic_xor(dst, val)
- })
-}
-
-
-/**
- * An atomic fence.
- *
- * A fence 'A' which has `Release` ordering semantics, synchronizes with a
- * fence 'B' with (at least) `Acquire` semantics, if and only if there exists
- * atomic operations X and Y, both operating on some atomic object 'M' such
- * that A is sequenced before X, Y is synchronized before B and Y observers
- * the change to M. This provides a happens-before dependence between A and B.
- *
- * Atomic operations with `Release` or `Acquire` semantics can also synchronize
- * with a fence.
- *
- * A fence with has `SeqCst` ordering, in addition to having both `Acquire` and
- * `Release` semantics, participates in the global program order of the other
- * `SeqCst` operations and/or fences.
- *
- * Accepts `Acquire`, `Release`, `AcqRel` and `SeqCst` orderings.
- */
-#[inline]
-pub fn fence(order: Ordering) {
- unsafe {
- match order {
- Acquire => intrinsics::atomic_fence_acq(),
- Release => intrinsics::atomic_fence_rel(),
- AcqRel => intrinsics::atomic_fence_rel(),
- _ => intrinsics::atomic_fence(),
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use option::*;
- use super::*;
-
- #[test]
- fn flag() {
- let mut flg = AtomicFlag::new();
- assert!(!flg.test_and_set(SeqCst));
- assert!(flg.test_and_set(SeqCst));
-
- flg.clear(SeqCst);
- assert!(!flg.test_and_set(SeqCst));
- }
-
- #[test]
- fn option_empty() {
- let mut option: AtomicOption<()> = AtomicOption::empty();
- assert!(option.is_empty(SeqCst));
- }
-
- #[test]
- fn option_swap() {
- let mut p = AtomicOption::new(~1);
- let a = ~2;
-
- let b = p.swap(a, SeqCst);
-
- assert_eq!(b, Some(~1));
- assert_eq!(p.take(SeqCst), Some(~2));
- }
-
- #[test]
- fn option_take() {
- let mut p = AtomicOption::new(~1);
-
- assert_eq!(p.take(SeqCst), Some(~1));
- assert_eq!(p.take(SeqCst), None);
-
- let p2 = ~2;
- p.swap(p2, SeqCst);
-
- assert_eq!(p.take(SeqCst), Some(~2));
- }
-
- #[test]
- fn option_fill() {
- let mut p = AtomicOption::new(~1);
- assert!(p.fill(~2, SeqCst).is_some()); // should fail; shouldn't leak!
- assert_eq!(p.take(SeqCst), Some(~1));
-
- assert!(p.fill(~2, SeqCst).is_none()); // shouldn't fail
- assert_eq!(p.take(SeqCst), Some(~2));
- }
-
- #[test]
- fn bool_and() {
- let mut a = AtomicBool::new(true);
- assert_eq!(a.fetch_and(false, SeqCst),true);
- assert_eq!(a.load(SeqCst),false);
- }
-
- static mut S_FLAG : AtomicFlag = INIT_ATOMIC_FLAG;
- static mut S_BOOL : AtomicBool = INIT_ATOMIC_BOOL;
- static mut S_INT : AtomicInt = INIT_ATOMIC_INT;
- static mut S_UINT : AtomicUint = INIT_ATOMIC_UINT;
-
- #[test]
- fn static_init() {
- unsafe {
- assert!(!S_FLAG.test_and_set(SeqCst));
- assert!(!S_BOOL.load(SeqCst));
- assert!(S_INT.load(SeqCst) == 0);
- assert!(S_UINT.load(SeqCst) == 0);
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Dynamic library facilities.
-
-A simple wrapper over the platform's dynamic library facilities
-
-*/
-use c_str::ToCStr;
-use cast;
-use path;
-use libc;
-use ops::*;
-use option::*;
-use result::*;
-
-pub struct DynamicLibrary { priv handle: *libc::c_void }
-
-impl Drop for DynamicLibrary {
- fn drop(&mut self) {
- match dl::check_for_errors_in(|| {
- unsafe {
- dl::close(self.handle)
- }
- }) {
- Ok(()) => {},
- Err(str) => fail!("{}", str)
- }
- }
-}
-
-impl DynamicLibrary {
- /// Lazily open a dynamic library. When passed None it gives a
- /// handle to the calling process
- pub fn open(filename: Option<&path::Path>) -> Result<DynamicLibrary, ~str> {
- unsafe {
- let maybe_library = dl::check_for_errors_in(|| {
- match filename {
- Some(name) => dl::open_external(name),
- None => dl::open_internal()
- }
- });
-
- // The dynamic library must not be constructed if there is
- // an error opening the library so the destructor does not
- // run.
- match maybe_library {
- Err(err) => Err(err),
- Ok(handle) => Ok(DynamicLibrary { handle: handle })
- }
- }
- }
-
- /// Access the value at the symbol of the dynamic library
- pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, ~str> {
- // This function should have a lifetime constraint of 'self on
- // T but that feature is still unimplemented
-
- let maybe_symbol_value = dl::check_for_errors_in(|| {
- symbol.with_c_str(|raw_string| {
- dl::symbol(self.handle, raw_string)
- })
- });
-
- // The value must not be constructed if there is an error so
- // the destructor does not run.
- match maybe_symbol_value {
- Err(err) => Err(err),
- Ok(symbol_value) => Ok(cast::transmute(symbol_value))
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use option::*;
- use result::*;
- use path::*;
- use libc;
-
- #[test]
- #[ignore(cfg(windows))] // FIXME #8818
- #[ignore(cfg(target_os="android"))] // FIXME(#10379)
- fn test_loading_cosine() {
- // The math library does not need to be loaded since it is already
- // statically linked in
- let libm = match DynamicLibrary::open(None) {
- Err(error) => fail!("Could not load self as module: {}", error),
- Ok(libm) => libm
- };
-
- let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
- match libm.symbol("cos") {
- Err(error) => fail!("Could not load function cos: {}", error),
- Ok(cosine) => cosine
- }
- };
-
- let argument = 0.0;
- let expected_result = 1.0;
- let result = cosine(argument);
- if result != expected_result {
- fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
- expected_result, result)
- }
- }
-
- #[test]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn test_errors_do_not_crash() {
- // Open /dev/null as a library to get an error, and make sure
- // that only causes an error, and not a crash.
- let path = GenericPath::new("/dev/null");
- match DynamicLibrary::open(Some(&path)) {
- Err(_) => {}
- Ok(_) => fail!("Successfully opened the empty library.")
- }
- }
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-pub mod dl {
- use c_str::ToCStr;
- use libc;
- use path;
- use ptr;
- use str;
- use unstable::sync::atomically;
- use result::*;
-
- pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
- filename.with_c_str(|raw_name| {
- dlopen(raw_name, Lazy as libc::c_int)
- })
- }
-
- pub unsafe fn open_internal() -> *libc::c_void {
- dlopen(ptr::null(), Lazy as libc::c_int)
- }
-
- pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, ~str> {
- use unstable::mutex::{Mutex, MUTEX_INIT};
- static mut lock: Mutex = MUTEX_INIT;
- unsafe {
- // dlerror isn't thread safe, so we need to lock around this entire
- // sequence. `atomically` asserts that we don't do anything that
- // would cause this task to be descheduled, which could deadlock
- // the scheduler if it happens while the lock is held.
- // FIXME #9105 use a Rust mutex instead of C++ mutexes.
- atomically(|| {
- lock.lock();
- let _old_error = dlerror();
-
- let result = f();
-
- let last_error = dlerror();
- let ret = if ptr::null() == last_error {
- Ok(result)
- } else {
- Err(str::raw::from_c_str(last_error))
- };
- lock.unlock();
- ret
- })
- }
- }
-
- pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
- dlsym(handle, symbol)
- }
- pub unsafe fn close(handle: *libc::c_void) {
- dlclose(handle); ()
- }
-
- pub enum RTLD {
- Lazy = 1,
- Now = 2,
- Global = 256,
- Local = 0,
- }
-
- #[link_name = "dl"]
- extern {
- fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
- fn dlerror() -> *libc::c_char;
- fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
- fn dlclose(handle: *libc::c_void) -> libc::c_int;
- }
-}
-
-#[cfg(target_os = "win32")]
-pub mod dl {
- use os;
- use libc;
- use path;
- use ptr;
- use unstable::sync::atomically;
- use result::*;
-
- pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
- os::win32::as_utf16_p(filename.as_str().unwrap(), |raw_name| {
- LoadLibraryW(raw_name)
- })
- }
-
- pub unsafe fn open_internal() -> *libc::c_void {
- let handle = ptr::null();
- GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
- handle
- }
-
- pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, ~str> {
- unsafe {
- atomically(|| {
- SetLastError(0);
-
- let result = f();
-
- let error = os::errno();
- if 0 == error {
- Ok(result)
- } else {
- Err(format!("Error code {}", error))
- }
- })
- }
- }
-
- pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
- GetProcAddress(handle, symbol)
- }
- pub unsafe fn close(handle: *libc::c_void) {
- FreeLibrary(handle); ()
- }
-
- #[link_name = "kernel32"]
- extern "system" {
- fn SetLastError(error: u32);
- fn LoadLibraryW(name: *u16) -> *libc::c_void;
- fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
- handle: **libc::c_void) -> *libc::c_void;
- fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
- fn FreeLibrary(handle: *libc::c_void);
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-The Finally trait provides a method, `finally` on
-stack closures that emulates Java-style try/finally blocks.
-
-# Example
-
- ```
-(|| {
- ...
-}).finally(|| {
- always_run_this();
-})
- ```
-*/
-
-use ops::Drop;
-
-#[cfg(test)] use task::failing;
-
-pub trait Finally<T> {
- fn finally(&self, dtor: ||) -> T;
-}
-
-macro_rules! finally_fn {
- ($fnty:ty) => {
- impl<T> Finally<T> for $fnty {
- fn finally(&self, dtor: ||) -> T {
- let _d = Finallyalizer {
- dtor: dtor
- };
- (*self)()
- }
- }
- }
-}
-
-impl<'self,T> Finally<T> for 'self || -> T {
- fn finally(&self, dtor: ||) -> T {
- let _d = Finallyalizer {
- dtor: dtor
- };
-
- (*self)()
- }
-}
-
-finally_fn!(extern "Rust" fn() -> T)
-
-struct Finallyalizer<'self> {
- dtor: 'self ||
-}
-
-#[unsafe_destructor]
-impl<'self> Drop for Finallyalizer<'self> {
- fn drop(&mut self) {
- (self.dtor)();
- }
-}
-
-#[test]
-fn test_success() {
- let mut i = 0;
- (|| {
- i = 10;
- }).finally(|| {
- assert!(!failing());
- assert_eq!(i, 10);
- i = 20;
- });
- assert_eq!(i, 20);
-}
-
-#[test]
-#[should_fail]
-fn test_fail() {
- let mut i = 0;
- (|| {
- i = 10;
- fail!();
- }).finally(|| {
- assert!(failing());
- assert_eq!(i, 10);
- })
-}
-
-#[test]
-fn test_retval() {
- let closure: || -> int = || 10;
- let i = closure.finally(|| { });
- assert_eq!(i, 10);
-}
-
-#[test]
-fn test_compact() {
- fn do_some_fallible_work() {}
- fn but_always_run_this_function() { }
- do_some_fallible_work.finally(
- but_always_run_this_function);
-}
-
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! rustc compiler intrinsics.
-
-The corresponding definitions are in librustc/middle/trans/foreign.rs.
-
-# Atomics
-
-The atomic intrinsics provide common atomic operations on machine
-words, with multiple possible memory orderings. They obey the same
-semantics as C++11. See the LLVM documentation on [[atomics]].
-
-[atomics]: http://llvm.org/docs/Atomics.html
-
-A quick refresher on memory ordering:
-
-* Acquire - a barrier for acquiring a lock. Subsequent reads and writes
- take place after the barrier.
-* Release - a barrier for releasing a lock. Preceding reads and writes
- take place before the barrier.
-* Sequentially consistent - sequentially consistent operations are
- guaranteed to happen in order. This is the standard mode for working
- with atomic types and is equivalent to Java's `volatile`.
-
-*/
-
-// This is needed to prevent duplicate lang item definitions.
-#[cfg(test)]
-pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
-
-pub type GlueFn = extern "Rust" fn(*i8);
-
-// NB: this has to be kept in sync with `type_desc` in `rt`
-#[lang="ty_desc"]
-#[cfg(not(test))]
-pub struct TyDesc {
- // sizeof(T)
- size: uint,
-
- // alignof(T)
- align: uint,
-
- // Called on a copy of a value of type `T` *after* memcpy
- take_glue: GlueFn,
-
- // Called when a value of type `T` is no longer needed
- drop_glue: GlueFn,
-
- // Called by drop glue when a value of type `T` can be freed
- free_glue: GlueFn,
-
- // Called by reflection visitor to visit a value of type `T`
- visit_glue: GlueFn,
-
- // If T represents a box pointer (`@U` or `~U`), then
- // `borrow_offset` is the amount that the pointer must be adjusted
- // to find the payload. This is always derivable from the type
- // `U`, but in the case of `@Trait` or `~Trait` objects, the type
- // `U` is unknown.
- borrow_offset: uint,
-
- // Name corresponding to the type
- name: &'static str
-}
-
-#[lang="opaque"]
-#[cfg(not(test))]
-pub enum Opaque { }
-
-pub type Disr = u64;
-
-#[lang="ty_visitor"]
-#[cfg(not(test))]
-pub trait TyVisitor {
- fn visit_bot(&mut self) -> bool;
- fn visit_nil(&mut self) -> bool;
- fn visit_bool(&mut self) -> bool;
-
- fn visit_int(&mut self) -> bool;
- fn visit_i8(&mut self) -> bool;
- fn visit_i16(&mut self) -> bool;
- fn visit_i32(&mut self) -> bool;
- fn visit_i64(&mut self) -> bool;
-
- fn visit_uint(&mut self) -> bool;
- fn visit_u8(&mut self) -> bool;
- fn visit_u16(&mut self) -> bool;
- fn visit_u32(&mut self) -> bool;
- fn visit_u64(&mut self) -> bool;
-
- fn visit_f32(&mut self) -> bool;
- fn visit_f64(&mut self) -> bool;
-
- fn visit_char(&mut self) -> bool;
-
- fn visit_estr_box(&mut self) -> bool;
- fn visit_estr_uniq(&mut self) -> bool;
- fn visit_estr_slice(&mut self) -> bool;
- fn visit_estr_fixed(&mut self, n: uint, sz: uint, align: uint) -> bool;
-
- fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_ptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
-
- fn visit_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_evec_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
- mtbl: uint, inner: *TyDesc) -> bool;
-
- fn visit_enter_rec(&mut self, n_fields: uint,
- sz: uint, align: uint) -> bool;
- fn visit_rec_field(&mut self, i: uint, name: &str,
- mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_leave_rec(&mut self, n_fields: uint,
- sz: uint, align: uint) -> bool;
-
- fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
- sz: uint, align: uint) -> bool;
- fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
- mtbl: uint, inner: *TyDesc) -> bool;
- fn visit_leave_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
- sz: uint, align: uint) -> bool;
-
- fn visit_enter_tup(&mut self, n_fields: uint,
- sz: uint, align: uint) -> bool;
- fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool;
- fn visit_leave_tup(&mut self, n_fields: uint,
- sz: uint, align: uint) -> bool;
-
- fn visit_enter_enum(&mut self, n_variants: uint,
- get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
- sz: uint, align: uint) -> bool;
- fn visit_enter_enum_variant(&mut self, variant: uint,
- disr_val: Disr,
- n_fields: uint,
- name: &str) -> bool;
- fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool;
- fn visit_leave_enum_variant(&mut self, variant: uint,
- disr_val: Disr,
- n_fields: uint,
- name: &str) -> bool;
- fn visit_leave_enum(&mut self, n_variants: uint,
- get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
- sz: uint, align: uint) -> bool;
-
- fn visit_enter_fn(&mut self, purity: uint, proto: uint,
- n_inputs: uint, retstyle: uint) -> bool;
- fn visit_fn_input(&mut self, i: uint, mode: uint, inner: *TyDesc) -> bool;
- fn visit_fn_output(&mut self, retstyle: uint, variadic: bool, inner: *TyDesc) -> bool;
- fn visit_leave_fn(&mut self, purity: uint, proto: uint,
- n_inputs: uint, retstyle: uint) -> bool;
-
- fn visit_trait(&mut self, name: &str) -> bool;
- fn visit_param(&mut self, i: uint) -> bool;
- fn visit_self(&mut self) -> bool;
- fn visit_type(&mut self) -> bool;
- fn visit_opaque_box(&mut self) -> bool;
- fn visit_closure_ptr(&mut self, ck: uint) -> bool;
-}
-
-extern "rust-intrinsic" {
- /// Abort the execution of the process.
- pub fn abort() -> !;
-
- /// Execute a breakpoint trap, for inspection by a debugger.
- pub fn breakpoint();
-
- /// Atomic compare and exchange, sequentially consistent.
- pub fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
- /// Atomic compare and exchange, acquire ordering.
- pub fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
- /// Atomic compare and exchange, release ordering.
- pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
-
- pub fn atomic_cxchg_acqrel(dst: &mut int, old: int, src: int) -> int;
- pub fn atomic_cxchg_relaxed(dst: &mut int, old: int, src: int) -> int;
-
-
- /// Atomic load, sequentially consistent.
- pub fn atomic_load(src: &int) -> int;
- /// Atomic load, acquire ordering.
- pub fn atomic_load_acq(src: &int) -> int;
-
- pub fn atomic_load_relaxed(src: &int) -> int;
-
- /// Atomic store, sequentially consistent.
- pub fn atomic_store(dst: &mut int, val: int);
- /// Atomic store, release ordering.
- pub fn atomic_store_rel(dst: &mut int, val: int);
-
- pub fn atomic_store_relaxed(dst: &mut int, val: int);
-
- /// Atomic exchange, sequentially consistent.
- pub fn atomic_xchg(dst: &mut int, src: int) -> int;
- /// Atomic exchange, acquire ordering.
- pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
- /// Atomic exchange, release ordering.
- pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_xchg_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_xchg_relaxed(dst: &mut int, src: int) -> int;
-
- /// Atomic addition, sequentially consistent.
- pub fn atomic_xadd(dst: &mut int, src: int) -> int;
- /// Atomic addition, acquire ordering.
- pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int;
- /// Atomic addition, release ordering.
- pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_xadd_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int;
-
- /// Atomic subtraction, sequentially consistent.
- pub fn atomic_xsub(dst: &mut int, src: int) -> int;
- /// Atomic subtraction, acquire ordering.
- pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int;
- /// Atomic subtraction, release ordering.
- pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_xsub_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_and(dst: &mut int, src: int) -> int;
- pub fn atomic_and_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_and_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_and_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_and_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_nand(dst: &mut int, src: int) -> int;
- pub fn atomic_nand_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_nand_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_nand_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_nand_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_or(dst: &mut int, src: int) -> int;
- pub fn atomic_or_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_or_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_or_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_or_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_xor(dst: &mut int, src: int) -> int;
- pub fn atomic_xor_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_xor_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_xor_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_xor_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_max(dst: &mut int, src: int) -> int;
- pub fn atomic_max_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_max_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_max_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_max_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_min(dst: &mut int, src: int) -> int;
- pub fn atomic_min_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_min_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_min_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_min_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_umin(dst: &mut int, src: int) -> int;
- pub fn atomic_umin_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_umin_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_umax(dst: &mut int, src: int) -> int;
- pub fn atomic_umax_acq(dst: &mut int, src: int) -> int;
- pub fn atomic_umax_rel(dst: &mut int, src: int) -> int;
- pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int;
- pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int;
-
- pub fn atomic_fence();
- pub fn atomic_fence_acq();
- pub fn atomic_fence_rel();
- pub fn atomic_fence_acqrel();
-
- /// The size of a type in bytes.
- ///
- /// This is the exact number of bytes in memory taken up by a
- /// value of the given type. In other words, a memset of this size
- /// would *exactly* overwrite a value. When laid out in vectors
- /// and structures there may be additional padding between
- /// elements.
- pub fn size_of<T>() -> uint;
-
- /// Move a value to a memory location containing a value.
- ///
- /// Drop glue is run on the destination, which must contain a
- /// valid Rust value.
- pub fn move_val<T>(dst: &mut T, src: T);
-
- /// Move a value to an uninitialized memory location.
- ///
- /// Drop glue is not run on the destination.
- pub fn move_val_init<T>(dst: &mut T, src: T);
-
- pub fn min_align_of<T>() -> uint;
- pub fn pref_align_of<T>() -> uint;
-
- /// Get a static pointer to a type descriptor.
- pub fn get_tydesc<T>() -> *TyDesc;
-
- /// Gets an identifier which is globally unique to the specified type. This
- /// function will return the same value for a type regardless of whichever
- /// crate it is invoked in.
- pub fn type_id<T: 'static>() -> u64;
-
- /// Create a value initialized to zero.
- ///
- /// `init` is unsafe because it returns a zeroed-out datum,
- /// which is unsafe unless T is POD. We don't have a POD
- /// kind yet. (See #4074).
- pub fn init<T>() -> T;
-
- /// Create an uninitialized value.
- pub fn uninit<T>() -> T;
-
- /// Move a value out of scope without running drop glue.
- ///
- /// `forget` is unsafe because the caller is responsible for
- /// ensuring the argument is deallocated already.
- pub fn forget<T>(_: T) -> ();
- pub fn transmute<T,U>(e: T) -> U;
-
- /// Returns `true` if a type requires drop glue.
- pub fn needs_drop<T>() -> bool;
-
- /// Returns `true` if a type is managed (will be allocated on the local heap)
- pub fn owns_managed<T>() -> bool;
-
- pub fn visit_tydesc(td: *TyDesc, tv: &mut TyVisitor);
-
- /// Get the address of the `__morestack` stack growth function.
- pub fn morestack_addr() -> *();
-
- /// Calculates the offset from a pointer. The offset *must* be in-bounds of
- /// the object, or one-byte-past-the-end. An arithmetic overflow is also
- /// undefined behaviour.
- ///
- /// This is implemented as an intrinsic to avoid converting to and from an
- /// integer, since the conversion would throw away aliasing information.
- pub fn offset<T>(dst: *T, offset: int) -> *T;
-
- /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
- /// a size of `count` * `size_of::<T>()` and an alignment of
- /// `min_align_of::<T>()`
- pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *T, count: uint);
-
- /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
- /// a size of `count` * `size_of::<T>()` and an alignment of
- /// `min_align_of::<T>()`
- pub fn copy_memory<T>(dst: *mut T, src: *T, count: uint);
-
- /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
- /// size of `count` * `size_of::<T>()` and an alignment of
- /// `min_align_of::<T>()`
- pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
-
- pub fn sqrtf32(x: f32) -> f32;
- pub fn sqrtf64(x: f64) -> f64;
-
- pub fn powif32(a: f32, x: i32) -> f32;
- pub fn powif64(a: f64, x: i32) -> f64;
-
- pub fn sinf32(x: f32) -> f32;
- pub fn sinf64(x: f64) -> f64;
-
- pub fn cosf32(x: f32) -> f32;
- pub fn cosf64(x: f64) -> f64;
-
- pub fn powf32(a: f32, x: f32) -> f32;
- pub fn powf64(a: f64, x: f64) -> f64;
-
- pub fn expf32(x: f32) -> f32;
- pub fn expf64(x: f64) -> f64;
-
- pub fn exp2f32(x: f32) -> f32;
- pub fn exp2f64(x: f64) -> f64;
-
- pub fn logf32(x: f32) -> f32;
- pub fn logf64(x: f64) -> f64;
-
- pub fn log10f32(x: f32) -> f32;
- pub fn log10f64(x: f64) -> f64;
-
- pub fn log2f32(x: f32) -> f32;
- pub fn log2f64(x: f64) -> f64;
-
- pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;
- pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;
-
- pub fn fabsf32(x: f32) -> f32;
- pub fn fabsf64(x: f64) -> f64;
-
- pub fn copysignf32(x: f32, y: f32) -> f32;
- pub fn copysignf64(x: f64, y: f64) -> f64;
-
- pub fn floorf32(x: f32) -> f32;
- pub fn floorf64(x: f64) -> f64;
-
- pub fn ceilf32(x: f32) -> f32;
- pub fn ceilf64(x: f64) -> f64;
-
- pub fn truncf32(x: f32) -> f32;
- pub fn truncf64(x: f64) -> f64;
-
- pub fn rintf32(x: f32) -> f32;
- pub fn rintf64(x: f64) -> f64;
-
- pub fn nearbyintf32(x: f32) -> f32;
- pub fn nearbyintf64(x: f64) -> f64;
-
- pub fn roundf32(x: f32) -> f32;
- pub fn roundf64(x: f64) -> f64;
-
- pub fn ctpop8(x: i8) -> i8;
- pub fn ctpop16(x: i16) -> i16;
- pub fn ctpop32(x: i32) -> i32;
- pub fn ctpop64(x: i64) -> i64;
-
- pub fn ctlz8(x: i8) -> i8;
- pub fn ctlz16(x: i16) -> i16;
- pub fn ctlz32(x: i32) -> i32;
- pub fn ctlz64(x: i64) -> i64;
-
- pub fn cttz8(x: i8) -> i8;
- pub fn cttz16(x: i16) -> i16;
- pub fn cttz32(x: i32) -> i32;
- pub fn cttz64(x: i64) -> i64;
-
- pub fn bswap16(x: i16) -> i16;
- pub fn bswap32(x: i32) -> i32;
- pub fn bswap64(x: i64) -> i64;
-
- pub fn i8_add_with_overflow(x: i8, y: i8) -> (i8, bool);
- pub fn i16_add_with_overflow(x: i16, y: i16) -> (i16, bool);
- pub fn i32_add_with_overflow(x: i32, y: i32) -> (i32, bool);
- pub fn i64_add_with_overflow(x: i64, y: i64) -> (i64, bool);
-
- pub fn u8_add_with_overflow(x: u8, y: u8) -> (u8, bool);
- pub fn u16_add_with_overflow(x: u16, y: u16) -> (u16, bool);
- pub fn u32_add_with_overflow(x: u32, y: u32) -> (u32, bool);
- pub fn u64_add_with_overflow(x: u64, y: u64) -> (u64, bool);
-
- pub fn i8_sub_with_overflow(x: i8, y: i8) -> (i8, bool);
- pub fn i16_sub_with_overflow(x: i16, y: i16) -> (i16, bool);
- pub fn i32_sub_with_overflow(x: i32, y: i32) -> (i32, bool);
- pub fn i64_sub_with_overflow(x: i64, y: i64) -> (i64, bool);
-
- pub fn u8_sub_with_overflow(x: u8, y: u8) -> (u8, bool);
- pub fn u16_sub_with_overflow(x: u16, y: u16) -> (u16, bool);
- pub fn u32_sub_with_overflow(x: u32, y: u32) -> (u32, bool);
- pub fn u64_sub_with_overflow(x: u64, y: u64) -> (u64, bool);
-
- pub fn i8_mul_with_overflow(x: i8, y: i8) -> (i8, bool);
- pub fn i16_mul_with_overflow(x: i16, y: i16) -> (i16, bool);
- pub fn i32_mul_with_overflow(x: i32, y: i32) -> (i32, bool);
- pub fn i64_mul_with_overflow(x: i64, y: i64) -> (i64, bool);
-
- pub fn u8_mul_with_overflow(x: u8, y: u8) -> (u8, bool);
- pub fn u16_mul_with_overflow(x: u16, y: u16) -> (u16, bool);
- pub fn u32_mul_with_overflow(x: u32, y: u32) -> (u32, bool);
- pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool);
-}
-
-#[cfg(target_endian = "little")] pub fn to_le16(x: i16) -> i16 { x }
-#[cfg(target_endian = "big")] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } }
-#[cfg(target_endian = "little")] pub fn to_le32(x: i32) -> i32 { x }
-#[cfg(target_endian = "big")] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } }
-#[cfg(target_endian = "little")] pub fn to_le64(x: i64) -> i64 { x }
-#[cfg(target_endian = "big")] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } }
-
-#[cfg(target_endian = "little")] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } }
-#[cfg(target_endian = "big")] pub fn to_be16(x: i16) -> i16 { x }
-#[cfg(target_endian = "little")] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } }
-#[cfg(target_endian = "big")] pub fn to_be32(x: i32) -> i32 { x }
-#[cfg(target_endian = "little")] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } }
-#[cfg(target_endian = "big")] pub fn to_be64(x: i64) -> i64 { x }
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Runtime calls emitted by the compiler.
-
-use c_str::ToCStr;
-use cast::transmute;
-use libc::{c_char, size_t, uintptr_t};
-use rt::task;
-use rt::borrowck;
-
-#[cold]
-#[lang="fail_"]
-pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
- task::begin_unwind_raw(expr, file, line);
-}
-
-#[cold]
-#[lang="fail_bounds_check"]
-pub fn fail_bounds_check(file: *c_char, line: size_t, index: size_t, len: size_t) -> ! {
- let msg = format!("index out of bounds: the len is {} but the index is {}",
- len as uint, index as uint);
- msg.with_c_str(|buf| fail_(buf, file, line))
-}
-
-#[lang="malloc"]
-pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
- ::rt::local_heap::local_malloc(td, size)
-}
-
-// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
-// inside a landing pad may corrupt the state of the exception handler. If a
-// problem occurs, call exit instead.
-#[lang="free"]
-pub unsafe fn local_free(ptr: *c_char) {
- ::rt::local_heap::local_free(ptr);
-}
-
-#[lang="borrow_as_imm"]
-#[inline]
-pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
- borrowck::borrow_as_imm(a, file, line)
-}
-
-#[lang="borrow_as_mut"]
-#[inline]
-pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
- borrowck::borrow_as_mut(a, file, line)
-}
-
-#[lang="record_borrow"]
-pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
- file: *c_char, line: size_t) {
- borrowck::record_borrow(a, old_ref_count, file, line)
-}
-
-#[lang="unrecord_borrow"]
-pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
- file: *c_char, line: size_t) {
- borrowck::unrecord_borrow(a, old_ref_count, file, line)
-}
-
-#[lang="return_to_mut"]
-#[inline]
-pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
- file: *c_char, line: size_t) {
- borrowck::return_to_mut(a, orig_ref_count, file, line)
-}
-
-#[lang="check_not_borrowed"]
-#[inline]
-pub unsafe fn check_not_borrowed(a: *u8,
- file: *c_char,
- line: size_t) {
- borrowck::check_not_borrowed(a, file, line)
-}
-
-#[lang="start"]
-pub fn start(main: *u8, argc: int, argv: **c_char) -> int {
- use rt;
-
- unsafe {
- return do rt::start(argc, argv as **u8) {
- let main: extern "Rust" fn() = transmute(main);
- main();
- };
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[doc(hidden)];
-
-use comm::{GenericChan, GenericPort};
-use comm;
-use prelude::*;
-use task;
-use libc::uintptr_t;
-
-pub mod dynamic_lib;
-
-pub mod finally;
-pub mod intrinsics;
-pub mod simd;
-#[cfg(not(test))]
-pub mod lang;
-pub mod sync;
-pub mod mutex;
-pub mod atomics;
-pub mod raw;
-
-/**
-
-Start a new thread outside of the current runtime context and wait
-for it to terminate.
-
-The executing thread has no access to a task pointer and will be using
-a normal large stack.
-*/
-pub fn run_in_bare_thread(f: proc()) {
- use cell::Cell;
- use rt::thread::Thread;
-
- let f_cell = Cell::new(f);
- let (port, chan) = comm::stream();
- // FIXME #4525: Unfortunate that this creates an extra scheduler but it's
- // necessary since rust_raw_thread_join is blocking
- do task::spawn_sched(task::SingleThreaded) {
- Thread::start(f_cell.take()).join();
- chan.send(());
- }
- port.recv();
-}
-
-#[test]
-fn test_run_in_bare_thread() {
- let i = 100;
- do run_in_bare_thread {
- assert_eq!(i, 100);
- }
-}
-
-#[test]
-fn test_run_in_bare_thread_exchange() {
- // Does the exchange heap work without the runtime?
- let i = ~100;
- do run_in_bare_thread {
- assert!(i == ~100);
- }
-}
-
-/// Dynamically inquire about whether we're running under V.
-/// You should usually not use this unless your test definitely
-/// can't run correctly un-altered. Valgrind is there to help
-/// you notice weirdness in normal, un-doctored code paths!
-pub fn running_on_valgrind() -> bool {
- unsafe { rust_running_on_valgrind() != 0 }
-}
-
-extern {
- fn rust_running_on_valgrind() -> uintptr_t;
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A native mutex and condition variable type
-//!
-//! This module contains bindings to the platform's native mutex/condition
-//! variable primitives. It provides a single type, `Mutex`, which can be
-//! statically initialized via the `MUTEX_INIT` value. This object serves as both a
-//! mutex and a condition variable simultaneously.
-//!
-//! The lock is lazily initialized, but it can only be unsafely destroyed. A
-//! statically initialized lock doesn't necessarily have a time at which it can
-//! get deallocated. For this reason, there is no `Drop` implementation of the
-//! mutex, but rather the `destroy()` method must be invoked manually if
-//! destruction of the mutex is desired.
-//!
-//! It is not recommended to use this type for idiomatic rust use. This type is
-//! appropriate where no other options are available, but other rust concurrency
-//! primitives should be used before this type.
-//!
-//! # Example
-//!
-//! use std::unstable::mutex::{Mutex, MUTEX_INIT};
-//!
-//! // Use a statically initialized mutex
-//! static mut lock: Mutex = MUTEX_INIT;
-//!
-//! unsafe {
-//! lock.lock();
-//! lock.unlock();
-//! }
-//!
-//! // Use a normally initialied mutex
-//! let mut lock = Mutex::new();
-//! unsafe {
-//! lock.lock();
-//! lock.unlock();
-//! lock.destroy();
-//! }
-
-#[allow(non_camel_case_types)];
-
-use libc::c_void;
-use unstable::atomics;
-
-pub struct Mutex {
- // pointers for the lock/cond handles, atomically updated
- priv lock: atomics::AtomicUint,
- priv cond: atomics::AtomicUint,
-}
-
-pub static MUTEX_INIT: Mutex = Mutex {
- lock: atomics::INIT_ATOMIC_UINT,
- cond: atomics::INIT_ATOMIC_UINT,
-};
-
-impl Mutex {
- /// Creates a new mutex, with the lock/condition variable pre-initialized
- pub unsafe fn new() -> Mutex {
- Mutex {
- lock: atomics::AtomicUint::new(imp::init_lock() as uint),
- cond: atomics::AtomicUint::new(imp::init_cond() as uint),
- }
- }
-
- /// Creates a new mutex, with the lock/condition variable not initialized.
- /// This is the same as initializing from the MUTEX_INIT static.
- pub unsafe fn empty() -> Mutex {
- Mutex {
- lock: atomics::AtomicUint::new(0),
- cond: atomics::AtomicUint::new(0),
- }
- }
-
- /// Creates a new copy of this mutex. This is an unsafe operation because
- /// there is no reference counting performed on this type.
- ///
- /// This function may only be called on mutexes which have had both the
- /// internal condition variable and lock initialized. This means that the
- /// mutex must have been created via `new`, or usage of it has already
- /// initialized the internal handles.
- ///
- /// This is a dangerous function to call as both this mutex and the returned
- /// mutex will share the same handles to the underlying mutex/condition
- /// variable. Care must be taken to ensure that deallocation happens
- /// accordingly.
- pub unsafe fn clone(&self) -> Mutex {
- let lock = self.lock.load(atomics::Relaxed);
- let cond = self.cond.load(atomics::Relaxed);
- assert!(lock != 0);
- assert!(cond != 0);
- Mutex {
- lock: atomics::AtomicUint::new(lock),
- cond: atomics::AtomicUint::new(cond),
- }
- }
-
- /// Acquires this lock. This assumes that the current thread does not
- /// already hold the lock.
- pub unsafe fn lock(&mut self) { imp::lock(self.getlock()) }
-
- /// Attempts to acquire the lock. The value returned is whether the lock was
- /// acquired or not
- pub unsafe fn trylock(&mut self) -> bool { imp::trylock(self.getlock()) }
-
- /// Unlocks the lock. This assumes that the current thread already holds the
- /// lock.
- pub unsafe fn unlock(&mut self) { imp::unlock(self.getlock()) }
-
- /// Block on the internal condition variable.
- ///
- /// This function assumes that the lock is already held
- pub unsafe fn wait(&mut self) { imp::wait(self.getcond(), self.getlock()) }
-
- /// Signals a thread in `wait` to wake up
- pub unsafe fn signal(&mut self) { imp::signal(self.getcond()) }
-
- /// This function is especially unsafe because there are no guarantees made
- /// that no other thread is currently holding the lock or waiting on the
- /// condition variable contained inside.
- pub unsafe fn destroy(&mut self) {
- let lock = self.lock.swap(0, atomics::Relaxed);
- let cond = self.cond.swap(0, atomics::Relaxed);
- if lock != 0 { imp::free_lock(lock) }
- if cond != 0 { imp::free_cond(cond) }
- }
-
- unsafe fn getlock(&mut self) -> *c_void {
- match self.lock.load(atomics::Relaxed) {
- 0 => {}
- n => return n as *c_void
- }
- let lock = imp::init_lock();
- match self.lock.compare_and_swap(0, lock, atomics::SeqCst) {
- 0 => return lock as *c_void,
- _ => {}
- }
- imp::free_lock(lock);
- return self.lock.load(atomics::Relaxed) as *c_void;
- }
-
- unsafe fn getcond(&mut self) -> *c_void {
- match self.cond.load(atomics::Relaxed) {
- 0 => {}
- n => return n as *c_void
- }
- let cond = imp::init_cond();
- match self.cond.compare_and_swap(0, cond, atomics::SeqCst) {
- 0 => return cond as *c_void,
- _ => {}
- }
- imp::free_cond(cond);
- return self.cond.load(atomics::Relaxed) as *c_void;
- }
-}
-
-#[cfg(unix)]
-mod imp {
- use libc::c_void;
- use libc;
- use ptr;
-
- type pthread_mutex_t = libc::c_void;
- type pthread_mutexattr_t = libc::c_void;
- type pthread_cond_t = libc::c_void;
- type pthread_condattr_t = libc::c_void;
-
- pub unsafe fn init_lock() -> uint {
- let block = libc::malloc(rust_pthread_mutex_t_size() as libc::size_t);
- assert!(!block.is_null());
- let n = pthread_mutex_init(block, ptr::null());
- assert_eq!(n, 0);
- return block as uint;
- }
-
- pub unsafe fn init_cond() -> uint {
- let block = libc::malloc(rust_pthread_cond_t_size() as libc::size_t);
- assert!(!block.is_null());
- let n = pthread_cond_init(block, ptr::null());
- assert_eq!(n, 0);
- return block as uint;
- }
-
- pub unsafe fn free_lock(h: uint) {
- let block = h as *c_void;
- assert_eq!(pthread_mutex_destroy(block), 0);
- libc::free(block);
- }
-
- pub unsafe fn free_cond(h: uint) {
- let block = h as *c_void;
- assert_eq!(pthread_cond_destroy(block), 0);
- libc::free(block);
- }
-
- pub unsafe fn lock(l: *pthread_mutex_t) {
- assert_eq!(pthread_mutex_lock(l), 0);
- }
-
- pub unsafe fn trylock(l: *c_void) -> bool {
- pthread_mutex_trylock(l) == 0
- }
-
- pub unsafe fn unlock(l: *pthread_mutex_t) {
- assert_eq!(pthread_mutex_unlock(l), 0);
- }
-
- pub unsafe fn wait(cond: *pthread_cond_t, m: *pthread_mutex_t) {
- assert_eq!(pthread_cond_wait(cond, m), 0);
- }
-
- pub unsafe fn signal(cond: *pthread_cond_t) {
- assert_eq!(pthread_cond_signal(cond), 0);
- }
-
- extern {
- fn rust_pthread_mutex_t_size() -> libc::c_int;
- fn rust_pthread_cond_t_size() -> libc::c_int;
- }
-
- extern {
- fn pthread_mutex_init(lock: *pthread_mutex_t,
- attr: *pthread_mutexattr_t) -> libc::c_int;
- fn pthread_mutex_destroy(lock: *pthread_mutex_t) -> libc::c_int;
- fn pthread_cond_init(cond: *pthread_cond_t,
- attr: *pthread_condattr_t) -> libc::c_int;
- fn pthread_cond_destroy(cond: *pthread_cond_t) -> libc::c_int;
- fn pthread_mutex_lock(lock: *pthread_mutex_t) -> libc::c_int;
- fn pthread_mutex_trylock(lock: *pthread_mutex_t) -> libc::c_int;
- fn pthread_mutex_unlock(lock: *pthread_mutex_t) -> libc::c_int;
-
- fn pthread_cond_wait(cond: *pthread_cond_t,
- lock: *pthread_mutex_t) -> libc::c_int;
- fn pthread_cond_signal(cond: *pthread_cond_t) -> libc::c_int;
- }
-}
-
-#[cfg(windows)]
-mod imp {
- use libc;
- use libc::{HANDLE, BOOL, LPSECURITY_ATTRIBUTES, c_void, DWORD, LPCSTR};
- use ptr;
- type LPCRITICAL_SECTION = *c_void;
- static SPIN_COUNT: DWORD = 4000;
-
- pub unsafe fn init_lock() -> uint {
- let block = libc::malloc(rust_crit_section_size() as libc::size_t);
- assert!(!block.is_null());
- InitializeCriticalSectionAndSpinCount(block, SPIN_COUNT);
- return block as uint;
- }
-
- pub unsafe fn init_cond() -> uint {
- return CreateEventA(ptr::mut_null(), libc::FALSE, libc::FALSE,
- ptr::null()) as uint;
- }
-
- pub unsafe fn free_lock(h: uint) {
- DeleteCriticalSection(h as LPCRITICAL_SECTION);
- libc::free(h as *c_void);
- }
-
- pub unsafe fn free_cond(h: uint) {
- let block = h as HANDLE;
- libc::CloseHandle(block);
- }
-
- pub unsafe fn lock(l: *c_void) {
- EnterCriticalSection(l as LPCRITICAL_SECTION)
- }
-
- pub unsafe fn trylock(l: *c_void) -> bool {
- TryEnterCriticalSection(l as LPCRITICAL_SECTION) != 0
- }
-
- pub unsafe fn unlock(l: *c_void) {
- LeaveCriticalSection(l as LPCRITICAL_SECTION)
- }
-
- pub unsafe fn wait(cond: *c_void, m: *c_void) {
- unlock(m);
- WaitForSingleObject(cond as HANDLE, 0);
- lock(m);
- }
-
- pub unsafe fn signal(cond: *c_void) {
- assert!(SetEvent(cond as HANDLE) != 0);
- }
-
- extern {
- fn rust_crit_section_size() -> libc::c_int;
- }
-
- extern "system" {
- fn CreateEventA(lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- bManualReset: BOOL,
- bInitialState: BOOL,
- lpName: LPCSTR) -> HANDLE;
- fn InitializeCriticalSectionAndSpinCount(
- lpCriticalSection: LPCRITICAL_SECTION,
- dwSpinCount: DWORD) -> BOOL;
- fn DeleteCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
- fn EnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
- fn LeaveCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
- fn TryEnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION) -> BOOL;
- fn SetEvent(hEvent: HANDLE) -> BOOL;
- fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::{Mutex, MUTEX_INIT};
- use rt::thread::Thread;
-
- #[test]
- fn somke_lock() {
- static mut lock: Mutex = MUTEX_INIT;
- unsafe {
- lock.lock();
- lock.unlock();
- }
- }
-
- #[test]
- fn somke_cond() {
- static mut lock: Mutex = MUTEX_INIT;
- unsafe {
- let t = do Thread::start {
- lock.lock();
- lock.signal();
- lock.unlock();
- };
- lock.lock();
- lock.wait();
- lock.unlock();
- t.join();
- }
- }
-
- #[test]
- fn destroy_immediately() {
- unsafe {
- let mut m = Mutex::empty();
- m.destroy();
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cast;
-use unstable::intrinsics::TyDesc;
-
-/// The representation of a Rust managed box
-pub struct Box<T> {
- ref_count: uint,
- type_desc: *TyDesc,
- prev: *mut Box<T>,
- next: *mut Box<T>,
- data: T
-}
-
-/// The representation of a Rust vector
-pub struct Vec<T> {
- fill: uint,
- alloc: uint,
- data: T
-}
-
-/// The representation of a Rust string
-pub type String = Vec<u8>;
-
-/// The representation of a Rust slice
-pub struct Slice<T> {
- data: *T,
- len: uint
-}
-
-/// The representation of a Rust closure
-pub struct Closure {
- code: *(),
- env: *(),
-}
-
-/// This trait is meant to map equivalences between raw structs and their
-/// corresponding rust values.
-pub trait Repr<T> {
- /// This function "unwraps" a rust value (without consuming it) into its raw
- /// struct representation. This can be used to read/write different values
- /// for the struct. This is a safe method because by default it does not
- /// give write-access to the struct returned.
- #[inline]
- fn repr(&self) -> T { unsafe { cast::transmute_copy(self) } }
-}
-
-impl<'self, T> Repr<Slice<T>> for &'self [T] {}
-impl<'self> Repr<Slice<u8>> for &'self str {}
-impl<T> Repr<*Box<T>> for @T {}
-impl<T> Repr<*Box<Vec<T>>> for @[T] {}
-impl Repr<*String> for ~str {}
-impl Repr<*Box<String>> for @str {}
-
-// sure would be nice to have this
-// impl<T> Repr<*Vec<T>> for ~[T] {}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use cast;
-
- #[test]
- fn synthesize_closure() {
- unsafe {
- let x = 10;
- let f: |int| -> int = |y| x + y;
-
- assert_eq!(f(20), 30);
-
- let original_closure: Closure = cast::transmute(f);
-
- let actual_function_pointer = original_closure.code;
- let environment = original_closure.env;
-
- let new_closure = Closure {
- code: actual_function_pointer,
- env: environment
- };
-
- let new_f: |int| -> int = cast::transmute(new_closure);
- assert_eq!(new_f(20), 30);
- }
- }
-}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! SIMD vectors
-
-#[allow(non_camel_case_types)];
-
-#[simd]
-pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
-
-#[simd]
-pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
-
-#[simd]
-pub struct i32x4(i32, i32, i32, i32);
-
-#[simd]
-pub struct i64x2(i64, i64);
-
-#[simd]
-pub struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
-
-#[simd]
-pub struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
-
-#[simd]
-pub struct u32x4(u32, u32, u32, u32);
-
-#[simd]
-pub struct u64x2(u64, u64);
-
-#[simd]
-pub struct f32x4(f32, f32, f32, f32);
-
-#[simd]
-pub struct f64x2(f64, f64);
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cast;
-use cell::Cell;
-use comm;
-use ptr;
-use option::{Option,Some,None};
-use task;
-use unstable::atomics::{AtomicOption,AtomicUint,Acquire,Release,Relaxed,SeqCst};
-use unstable::finally::Finally;
-use unstable::mutex::Mutex;
-use ops::Drop;
-use clone::Clone;
-use kinds::Send;
-use vec;
-
-/// An atomically reference counted pointer.
-///
-/// Enforces no shared-memory safety.
-//#[unsafe_no_drop_flag] FIXME: #9758
-pub struct UnsafeArc<T> {
- data: *mut ArcData<T>,
-}
-
-pub enum UnsafeArcUnwrap<T> {
- UnsafeArcSelf(UnsafeArc<T>),
- UnsafeArcT(T)
-}
-
-impl<T> UnsafeArcUnwrap<T> {
- fn expect_t(self, msg: &'static str) -> T {
- match self {
- UnsafeArcSelf(_) => fail!(msg),
- UnsafeArcT(t) => t
- }
- }
-
- fn is_self(&self) -> bool {
- match *self {
- UnsafeArcSelf(_) => true,
- UnsafeArcT(_) => false
- }
- }
-}
-
-struct ArcData<T> {
- count: AtomicUint,
- // An unwrapper uses this protocol to communicate with the "other" task that
- // drops the last refcount on an arc. Unfortunately this can't be a proper
- // pipe protocol because the unwrapper has to access both stages at once.
- // FIXME(#7544): Maybe use AtomicPtr instead (to avoid xchg in take() later)?
- unwrapper: AtomicOption<(comm::ChanOne<()>, comm::PortOne<bool>)>,
- // FIXME(#3224) should be able to make this non-option to save memory
- data: Option<T>,
-}
-
-unsafe fn new_inner<T: Send>(data: T, refcount: uint) -> *mut ArcData<T> {
- let data = ~ArcData { count: AtomicUint::new(refcount),
- unwrapper: AtomicOption::empty(),
- data: Some(data) };
- cast::transmute(data)
-}
-
-impl<T: Send> UnsafeArc<T> {
- pub fn new(data: T) -> UnsafeArc<T> {
- unsafe { UnsafeArc { data: new_inner(data, 1) } }
- }
-
- /// As new(), but returns an extra pre-cloned handle.
- pub fn new2(data: T) -> (UnsafeArc<T>, UnsafeArc<T>) {
- unsafe {
- let ptr = new_inner(data, 2);
- (UnsafeArc { data: ptr }, UnsafeArc { data: ptr })
- }
- }
-
- /// As new(), but returns a vector of as many pre-cloned handles as requested.
- pub fn newN(data: T, num_handles: uint) -> ~[UnsafeArc<T>] {
- unsafe {
- if num_handles == 0 {
- ~[] // need to free data here
- } else {
- let ptr = new_inner(data, num_handles);
- vec::from_fn(num_handles, |_| UnsafeArc { data: ptr })
- }
- }
- }
-
- /// As newN(), but from an already-existing handle. Uses one xadd.
- pub fn cloneN(self, num_handles: uint) -> ~[UnsafeArc<T>] {
- if num_handles == 0 {
- ~[] // The "num_handles - 1" trick (below) fails in the 0 case.
- } else {
- unsafe {
- // Minus one because we are recycling the given handle's refcount.
- let old_count = (*self.data).count.fetch_add(num_handles - 1, Acquire);
- // let old_count = (*self.data).count.fetch_add(num_handles, Acquire);
- assert!(old_count >= 1);
- let ptr = self.data;
- cast::forget(self); // Don't run the destructor on this handle.
- vec::from_fn(num_handles, |_| UnsafeArc { data: ptr })
- }
- }
- }
-
- #[inline]
- pub fn get(&self) -> *mut T {
- unsafe {
- assert!((*self.data).count.load(Relaxed) > 0);
- let r: *mut T = (*self.data).data.get_mut_ref();
- return r;
- }
- }
-
- #[inline]
- pub fn get_immut(&self) -> *T {
- unsafe {
- assert!((*self.data).count.load(Relaxed) > 0);
- let r: *T = (*self.data).data.get_ref();
- return r;
- }
- }
-
- /// Wait until all other handles are dropped, then retrieve the enclosed
- /// data. See extra::arc::Arc for specific semantics documentation.
- /// If called when the task is already unkillable, unwrap will unkillably
- /// block; otherwise, an unwrapping task can be killed by linked failure.
- pub fn unwrap(self) -> T {
- unsafe {
- let mut this = self;
- // The ~ dtor needs to run if this code succeeds.
- let mut data: ~ArcData<T> = cast::transmute(this.data);
- // Set up the unwrap protocol.
- let (p1,c1) = comm::oneshot(); // ()
- let (p2,c2) = comm::oneshot(); // bool
- // Try to put our server end in the unwrapper slot.
- // This needs no barrier -- it's protected by the release barrier on
- // the xadd, and the acquire+release barrier in the destructor's xadd.
- if data.unwrapper.fill(~(c1,p2), Relaxed).is_none() {
- // Got in. Tell this handle's destructor not to run (we are now it).
- this.data = ptr::mut_null();
- // Drop our own reference.
- let old_count = data.count.fetch_sub(1, Release);
- assert!(old_count >= 1);
- if old_count == 1 {
- // We were the last owner. Can unwrap immediately.
- // AtomicOption's destructor will free the server endpoint.
- // FIXME(#3224): it should be like this
- // let ~ArcData { data: user_data, _ } = data;
- // user_data
- data.data.take_unwrap()
- } else {
- // The *next* person who sees the refcount hit 0 will wake us.
- let p1 = Cell::new(p1); // argh
- // Unlike the above one, this cell is necessary. It will get
- // taken either in the do block or in the finally block.
- let c2_and_data = Cell::new((c2,data));
- (|| {
- p1.take().recv();
- // Got here. Back in the 'unkillable' without getting killed.
- let (c2, data) = c2_and_data.take();
- c2.send(true);
- // FIXME(#3224): it should be like this
- // let ~ArcData { data: user_data, _ } = data;
- // user_data
- let mut data = data;
- data.data.take_unwrap()
- }).finally(|| {
- if task::failing() {
- // Killed during wait. Because this might happen while
- // someone else still holds a reference, we can't free
- // the data now; the "other" last refcount will free it.
- let (c2, data) = c2_and_data.take();
- c2.send(false);
- cast::forget(data);
- } else {
- assert!(c2_and_data.is_empty());
- }
- })
- }
- } else {
- // If 'put' returns the server end back to us, we were rejected;
- // someone else was trying to unwrap. Avoid guaranteed deadlock.
- cast::forget(data);
- fail!("Another task is already unwrapping this Arc!");
- }
- }
- }
-
- /// As unwrap above, but without blocking. Returns 'UnsafeArcSelf(self)' if this is
- /// not the last reference; 'UnsafeArcT(unwrapped_data)' if so.
- pub fn try_unwrap(mut self) -> UnsafeArcUnwrap<T> {
- unsafe {
- // The ~ dtor needs to run if this code succeeds.
- let mut data: ~ArcData<T> = cast::transmute(self.data);
- // This can of course race with anybody else who has a handle, but in
- // such a case, the returned count will always be at least 2. If we
- // see 1, no race was possible. All that matters is 1 or not-1.
- let count = data.count.load(Acquire);
- assert!(count >= 1);
- // The more interesting race is one with an unwrapper. They may have
- // already dropped their count -- but if so, the unwrapper pointer
- // will have been set first, which the barriers ensure we will see.
- // (Note: using is_empty(), not take(), to not free the unwrapper.)
- if count == 1 && data.unwrapper.is_empty(Acquire) {
- // Tell this handle's destructor not to run (we are now it).
- self.data = ptr::mut_null();
- // FIXME(#3224) as above
- UnsafeArcT(data.data.take_unwrap())
- } else {
- cast::forget(data);
- UnsafeArcSelf(self)
- }
- }
- }
-}
-
-impl<T: Send> Clone for UnsafeArc<T> {
- fn clone(&self) -> UnsafeArc<T> {
- unsafe {
- // This barrier might be unnecessary, but I'm not sure...
- let old_count = (*self.data).count.fetch_add(1, Acquire);
- assert!(old_count >= 1);
- return UnsafeArc { data: self.data };
- }
- }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for UnsafeArc<T>{
- fn drop(&mut self) {
- unsafe {
- // Happens when destructing an unwrapper's handle and from `#[unsafe_no_drop_flag]`
- if self.data.is_null() {
- return
- }
- let mut data: ~ArcData<T> = cast::transmute(self.data);
- // Must be acquire+release, not just release, to make sure this
- // doesn't get reordered to after the unwrapper pointer load.
- let old_count = data.count.fetch_sub(1, SeqCst);
- assert!(old_count >= 1);
- if old_count == 1 {
- // Were we really last, or should we hand off to an
- // unwrapper? It's safe to not xchg because the unwrapper
- // will set the unwrap lock *before* dropping his/her
- // reference. In effect, being here means we're the only
- // *awake* task with the data.
- match data.unwrapper.take(Acquire) {
- Some(~(message,response)) => {
- // Send 'ready' and wait for a response.
- message.send(());
- // Unkillable wait. Message guaranteed to come.
- if response.recv() {
- // Other task got the data.
- cast::forget(data);
- } else {
- // Other task was killed. drop glue takes over.
- }
- }
- None => {
- // drop glue takes over.
- }
- }
- } else {
- cast::forget(data);
- }
- }
- }
-}
-
-
-/****************************************************************************/
-
-/**
- * Enables a runtime assertion that no operation in the argument closure shall
- * use scheduler operations (deschedule, recv, spawn, etc). This is for use with
- * pthread mutexes, which may block the entire scheduler thread, rather than
- * just one task, and is hence prone to deadlocks if mixed with descheduling.
- *
- * NOTE: THIS DOES NOT PROVIDE LOCKING, or any sort of critical-section
- * synchronization whatsoever. It only makes sense to use for CPU-local issues.
- */
-// FIXME(#8140) should not be pub
-pub unsafe fn atomically<U>(f: || -> U) -> U {
- use rt::task::{Task, GreenTask, SchedTask};
- use rt::local::Local;
-
- let task_opt: Option<*mut Task> = Local::try_unsafe_borrow();
- match task_opt {
- Some(t) => {
- match (*t).task_type {
- GreenTask(_) => {
- (|| {
- (*t).death.inhibit_deschedule();
- f()
- }).finally(|| (*t).death.allow_deschedule())
- }
- SchedTask => f()
- }
- }
- None => f()
- }
-}
-
-pub struct LittleLock {
- priv l: Mutex,
-}
-
-pub struct LittleGuard<'a> {
- priv l: &'a mut Mutex,
-}
-
-impl Drop for LittleLock {
- fn drop(&mut self) {
- unsafe { self.l.destroy(); }
- }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for LittleGuard<'a> {
- fn drop(&mut self) {
- unsafe { self.l.unlock(); }
- }
-}
-
-impl LittleLock {
- pub fn new() -> LittleLock {
- unsafe { LittleLock { l: Mutex::new() } }
- }
-
- pub unsafe fn lock<'a>(&'a mut self) -> LittleGuard<'a> {
- self.l.lock();
- LittleGuard { l: &mut self.l }
- }
-
- pub unsafe fn try_lock<'a>(&'a mut self) -> Option<LittleGuard<'a>> {
- if self.l.trylock() {
- Some(LittleGuard { l: &mut self.l })
- } else {
- None
- }
- }
-
- pub unsafe fn signal(&mut self) {
- self.l.signal();
- }
-}
-
-impl<'a> LittleGuard<'a> {
- pub unsafe fn wait(&mut self) {
- self.l.wait();
- }
-}
-
-struct ExData<T> {
- lock: LittleLock,
- failed: bool,
- data: T,
-}
-
-/**
- * An arc over mutable data that is protected by a lock. For library use only.
- *
- * # Safety note
- *
- * This uses a pthread mutex, not one that's aware of the userspace scheduler.
- * The user of an Exclusive must be careful not to invoke any functions that may
- * reschedule the task while holding the lock, or deadlock may result. If you
- * need to block or deschedule while accessing shared state, use extra::sync::RWArc.
- */
-pub struct Exclusive<T> {
- priv x: UnsafeArc<ExData<T>>
-}
-
-impl<T:Send> Clone for Exclusive<T> {
- // Duplicate an Exclusive Arc, as std::arc::clone.
- fn clone(&self) -> Exclusive<T> {
- Exclusive { x: self.x.clone() }
- }
-}
-
-impl<T:Send> Exclusive<T> {
- pub fn new(user_data: T) -> Exclusive<T> {
- let data = ExData {
- lock: LittleLock::new(),
- failed: false,
- data: user_data
- };
- Exclusive {
- x: UnsafeArc::new(data)
- }
- }
-
- // Exactly like std::arc::MutexArc,access(), but with the LittleLock
- // instead of a proper mutex. Same reason for being unsafe.
- //
- // Currently, scheduling operations (i.e., descheduling, receiving on a pipe,
- // accessing the provided condition variable) are prohibited while inside
- // the Exclusive. Supporting that is a work in progress.
- #[inline]
- pub unsafe fn with<U>(&self, f: |x: &mut T| -> U) -> U {
- let rec = self.x.get();
- let _l = (*rec).lock.lock();
- if (*rec).failed {
- fail!("Poisoned Exclusive::new - another task failed inside!");
- }
- (*rec).failed = true;
- let result = f(&mut (*rec).data);
- (*rec).failed = false;
- result
- }
-
- #[inline]
- pub unsafe fn with_imm<U>(&self, f: |x: &T| -> U) -> U {
- self.with(|x| f(cast::transmute_immut(x)))
- }
-
- #[inline]
- pub unsafe fn hold_and_signal(&self, f: |x: &mut T|) {
- let rec = self.x.get();
- let _l = (*rec).lock.lock();
- if (*rec).failed {
- fail!("Poisoned Exclusive::new - another task failed inside!");
- }
- (*rec).failed = true;
- f(&mut (*rec).data);
- (*rec).failed = false;
- (*rec).lock.signal();
- }
-
- #[inline]
- pub unsafe fn hold_and_wait(&self, f: |x: &T| -> bool) {
- let rec = self.x.get();
- let mut l = (*rec).lock.lock();
- if (*rec).failed {
- fail!("Poisoned Exclusive::new - another task failed inside!");
- }
- (*rec).failed = true;
- let result = f(&(*rec).data);
- (*rec).failed = false;
- if result {
- l.wait();
- }
- }
-
- pub fn unwrap(self) -> T {
- let Exclusive { x: x } = self;
- // Someday we might need to unkillably unwrap an Exclusive, but not today.
- let inner = x.unwrap();
- let ExData { data: user_data, .. } = inner; // will destroy the LittleLock
- user_data
- }
-}
-
-#[cfg(test)]
-mod tests {
- use comm;
- use option::*;
- use prelude::*;
- use super::{Exclusive, UnsafeArc, atomically};
- use task;
- use util;
- use mem::size_of;
-
- //#[unsafe_no_drop_flag] FIXME: #9758
- #[ignore]
- #[test]
- fn test_size() {
- assert_eq!(size_of::<UnsafeArc<[int, ..10]>>(), size_of::<*[int, ..10]>());
- }
-
- #[test]
- fn test_atomically() {
- // NB. The whole runtime will abort on an 'atomic-sleep' violation,
- // so we can't really test for the converse behaviour.
- unsafe { atomically(|| ()) } task::deschedule(); // oughtn't fail
- }
-
- #[test]
- fn exclusive_new_arc() {
- unsafe {
- let mut futures = ~[];
-
- let num_tasks = 10;
- let count = 10;
-
- let total = Exclusive::new(~0);
-
- for _ in range(0u, num_tasks) {
- let total = total.clone();
- let (port, chan) = comm::stream();
- futures.push(port);
-
- do task::spawn || {
- for _ in range(0u, count) {
- total.with(|count| **count += 1);
- }
- chan.send(());
- }
- };
-
- for f in futures.iter() { f.recv() }
-
- total.with(|total| assert!(**total == num_tasks * count));
- }
- }
-
- #[test] #[should_fail]
- fn exclusive_new_poison() {
- unsafe {
- // Tests that if one task fails inside of an Exclusive::new, subsequent
- // accesses will also fail.
- let x = Exclusive::new(1);
- let x2 = x.clone();
- do task::try || {
- x2.with(|one| assert_eq!(*one, 2))
- };
- x.with(|one| assert_eq!(*one, 1));
- }
- }
-
- #[test]
- fn arclike_newN() {
- // Tests that the many-refcounts-at-once constructors don't leak.
- let _ = UnsafeArc::new2(~~"hello");
- let x = UnsafeArc::newN(~~"hello", 0);
- assert_eq!(x.len(), 0)
- let x = UnsafeArc::newN(~~"hello", 1);
- assert_eq!(x.len(), 1)
- let x = UnsafeArc::newN(~~"hello", 10);
- assert_eq!(x.len(), 10)
- }
-
- #[test]
- fn arclike_cloneN() {
- // Tests that the many-refcounts-at-once special-clone doesn't leak.
- let x = UnsafeArc::new(~~"hello");
- let x = x.cloneN(0);
- assert_eq!(x.len(), 0);
- let x = UnsafeArc::new(~~"hello");
- let x = x.cloneN(1);
- assert_eq!(x.len(), 1);
- let x = UnsafeArc::new(~~"hello");
- let x = x.cloneN(10);
- assert_eq!(x.len(), 10);
- }
-
- #[test]
- fn arclike_unwrap_basic() {
- let x = UnsafeArc::new(~~"hello");
- assert!(x.unwrap() == ~~"hello");
- }
-
- #[test]
- fn arclike_try_unwrap() {
- let x = UnsafeArc::new(~~"hello");
- assert!(x.try_unwrap().expect_t("try_unwrap failed") == ~~"hello");
- }
-
- #[test]
- fn arclike_try_unwrap_fail() {
- let x = UnsafeArc::new(~~"hello");
- let x2 = x.clone();
- let left_x = x.try_unwrap();
- assert!(left_x.is_self());
- util::ignore(left_x);
- assert!(x2.try_unwrap().expect_t("try_unwrap none") == ~~"hello");
- }
-
- #[test]
- fn arclike_try_unwrap_unwrap_race() {
- // When an unwrap and a try_unwrap race, the unwrapper should always win.
- let x = UnsafeArc::new(~~"hello");
- let x2 = x.clone();
- let (p,c) = comm::stream();
- do task::spawn {
- c.send(());
- assert!(x2.unwrap() == ~~"hello");
- c.send(());
- }
- p.recv();
- task::deschedule(); // Try to make the unwrapper get blocked first.
- let left_x = x.try_unwrap();
- assert!(left_x.is_self());
- util::ignore(left_x);
- p.recv();
- }
-
- #[test]
- fn exclusive_new_unwrap_basic() {
- // Unlike the above, also tests no double-freeing of the LittleLock.
- let x = Exclusive::new(~~"hello");
- assert!(x.unwrap() == ~~"hello");
- }
-
- #[test]
- fn exclusive_new_unwrap_contended() {
- let x = Exclusive::new(~~"hello");
- let x2 = x.clone();
- do task::spawn {
- unsafe { x2.with(|_hello| ()); }
- task::deschedule();
- }
- assert!(x.unwrap() == ~~"hello");
-
- // Now try the same thing, but with the child task blocking.
- let x = Exclusive::new(~~"hello");
- let x2 = x.clone();
- let mut builder = task::task();
- let res = builder.future_result();
- do builder.spawn {
- assert!(x2.unwrap() == ~~"hello");
- }
- // Have to get rid of our reference before blocking.
- util::ignore(x);
- res.recv();
- }
-
- #[test] #[should_fail]
- fn exclusive_new_unwrap_conflict() {
- let x = Exclusive::new(~~"hello");
- let x2 = x.clone();
- let mut builder = task::task();
- let res = builder.future_result();
- do builder.spawn {
- assert!(x2.unwrap() == ~~"hello");
- }
- assert!(x.unwrap() == ~~"hello");
- assert!(res.recv().is_ok());
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Miscellaneous helpers for common patterns.
-
-use cast;
-use ptr;
-use prelude::*;
-use unstable::intrinsics;
-
-/// The identity function.
-#[inline]
-pub fn id<T>(x: T) -> T { x }
-
-/// Ignores a value.
-#[inline]
-pub fn ignore<T>(_x: T) { }
-
-/**
- * Swap the values at two mutable locations of the same type, without
- * deinitialising or copying either one.
- */
-#[inline]
-pub fn swap<T>(x: &mut T, y: &mut T) {
- unsafe {
- // Give ourselves some scratch space to work with
- let mut tmp: T = intrinsics::uninit();
- let t: *mut T = &mut tmp;
-
- // Perform the swap, `&mut` pointers never alias
- let x_raw: *mut T = x;
- let y_raw: *mut T = y;
- ptr::copy_nonoverlapping_memory(t, x_raw, 1);
- ptr::copy_nonoverlapping_memory(x, y_raw, 1);
- ptr::copy_nonoverlapping_memory(y, t, 1);
-
- // y and t now point to the same thing, but we need to completely forget `tmp`
- // because it's no longer relevant.
- cast::forget(tmp);
- }
-}
-
-/**
- * Replace the value at a mutable location with a new one, returning the old
- * value, without deinitialising or copying either one.
- */
-#[inline]
-pub fn replace<T>(dest: &mut T, mut src: T) -> T {
- swap(dest, &mut src);
- src
-}
-
-/// A non-copyable dummy type.
-#[deriving(Eq, TotalEq, Ord, TotalOrd)]
-#[unsafe_no_drop_flag]
-pub struct NonCopyable;
-
-impl Drop for NonCopyable {
- fn drop(&mut self) { }
-}
-
-/// A type with no inhabitants
-pub enum Void { }
-
-impl Void {
- /// A utility function for ignoring this uninhabited type
- pub fn uninhabited(self) -> ! {
- match self {
- // Nothing to match on
- }
- }
-}
-
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use clone::Clone;
- use ops::Drop;
- use option::{None, Some};
- use either::{Either, Left, Right};
- use mem::size_of;
-
- #[test]
- fn identity_crisis() {
- // Writing a test for the identity function. How did it come to this?
- let x = ~[(5, false)];
- //FIXME #3387 assert!(x.eq(id(x.clone())));
- let y = x.clone();
- assert!(x.eq(&id(y)));
- }
-
- #[test]
- fn test_swap() {
- let mut x = 31337;
- let mut y = 42;
- swap(&mut x, &mut y);
- assert_eq!(x, 42);
- assert_eq!(y, 31337);
- }
-
- #[test]
- fn test_replace() {
- let mut x = Some(NonCopyable);
- let y = replace(&mut x, None);
- assert!(x.is_none());
- assert!(y.is_some());
- }
-
- #[test]
- fn test_uninhabited() {
- let could_only_be_coin : Either <Void, ()> = Right (());
- match could_only_be_coin {
- Right (coin) => coin,
- Left (is_void) => is_void.uninhabited ()
- }
- }
-
- #[test]
- fn test_noncopyable() {
- assert_eq!(size_of::<NonCopyable>(), 0);
-
- // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct
-
- static mut did_run: bool = false;
-
- struct Foo { five: int }
-
- impl Drop for Foo {
- fn drop(&mut self) {
- assert_eq!(self.five, 5);
- unsafe {
- did_run = true;
- }
- }
- }
-
- {
- let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
- }
-
- unsafe { assert_eq!(did_run, true); }
- }
-}
-
-/// Completely miscellaneous language-construct benchmarks.
-#[cfg(test)]
-mod bench {
-
- use extra::test::BenchHarness;
- use option::{Some,None};
-
- // Static/dynamic method dispatch
-
- struct Struct {
- field: int
- }
-
- trait Trait {
- fn method(&self) -> int;
- }
-
- impl Trait for Struct {
- fn method(&self) -> int {
- self.field
- }
- }
-
- #[bench]
- fn trait_vtable_method_call(bh: &mut BenchHarness) {
- let s = Struct { field: 10 };
- let t = &s as &Trait;
- bh.iter(|| {
- t.method();
- });
- }
-
- #[bench]
- fn trait_static_method_call(bh: &mut BenchHarness) {
- let s = Struct { field: 10 };
- bh.iter(|| {
- s.method();
- });
- }
-
- // Overhead of various match forms
-
- #[bench]
- fn match_option_some(bh: &mut BenchHarness) {
- let x = Some(10);
- bh.iter(|| {
- let _q = match x {
- Some(y) => y,
- None => 11
- };
- });
- }
-
- #[bench]
- fn match_vec_pattern(bh: &mut BenchHarness) {
- let x = [1,2,3,4,5,6];
- bh.iter(|| {
- let _q = match x {
- [1,2,3,..] => 10,
- _ => 11
- };
- });
- }
-}
+++ /dev/null
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Vector manipulation
-
-The `vec` module contains useful code to help work with vector values.
-Vectors are Rust's list type. Vectors contain zero or more values of
-homogeneous types:
-
-```rust
-let int_vector = [1,2,3];
-let str_vector = ["one", "two", "three"];
- ```
-
-This is a big module, but for a high-level overview:
-
-## Structs
-
-Several structs that are useful for vectors, such as `VecIterator`, which
-represents iteration over a vector.
-
-## Traits
-
-A number of traits add methods that allow you to accomplish tasks with vectors.
-
-Traits defined for the `&[T]` type (a vector slice), have methods that can be
-called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
-These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
-case.
-
-An example is the method `.slice(a, b)` that returns an immutable "view" into
-a vector or a vector slice from the index interval `[a, b)`:
-
-```rust
-let numbers = [0, 1, 2];
-let last_numbers = numbers.slice(1, 3);
-// last_numbers is now &[1, 2]
- ```
-
-Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
-on such vectors. These methods deal with adding elements or otherwise changing
-the allocation of the vector.
-
-An example is the method `.push(element)` that will add an element at the end
-of the vector:
-
-```rust
-let mut numbers = ~[0, 1, 2];
-numbers.push(7);
-// numbers is now ~[0, 1, 2, 7];
- ```
-
-## Implementations of other traits
-
-Vectors are a very useful type, and so there's several implementations of
-traits from other modules. Some notable examples:
-
-* `Clone`
-* `Eq`, `Ord`, `TotalEq`, `TotalOrd` -- vectors can be compared,
- if the element type defines the corresponding trait.
-
-## Iteration
-
-The method `iter()` returns an iteration value for a vector or a vector slice.
-The iterator yields borrowed pointers to the vector's elements, so if the element
-type of the vector is `int`, the element type of the iterator is `&int`.
-
-```rust
-let numbers = [0, 1, 2];
-for &x in numbers.iter() {
- println!("{} is a number!", x);
-}
- ```
-
-* `.rev_iter()` returns an iterator with the same values as `.iter()`,
- but going in the reverse order, starting with the back element.
-* `.mut_iter()` returns an iterator that allows modifying each value.
-* `.move_iter()` converts an owned vector into an iterator that
- moves out a value from the vector each iteration.
-* Further iterators exist that split, chunk or permute the vector.
-
-## Function definitions
-
-There are a number of free functions that create or take vectors, for example:
-
-* Creating a vector, like `from_elem` and `from_fn`
-* Creating a vector with a given size: `with_capacity`
-* Modifying a vector and returning it, like `append`
-* Operations on paired elements, like `unzip`.
-
-*/
-
-#[warn(non_camel_case_types)];
-
-use cast;
-use clone::{Clone, DeepClone};
-use container::{Container, Mutable};
-use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
-use cmp;
-use default::Default;
-use iter::*;
-use libc::c_void;
-use num::{Integer, CheckedAdd, Saturating};
-use option::{None, Option, Some};
-use ptr::to_unsafe_ptr;
-use ptr;
-use ptr::RawPtr;
-use rt::global_heap::malloc_raw;
-use rt::global_heap::realloc_raw;
-use mem;
-use mem::size_of;
-use uint;
-use unstable::finally::Finally;
-use unstable::intrinsics;
-use unstable::intrinsics::{get_tydesc, owns_managed};
-use unstable::raw::{Box, Repr, Slice, Vec};
-use vec;
-use util;
-
-/**
- * Creates and initializes an owned vector.
- *
- * Creates an owned vector of size `n_elts` and initializes the elements
- * to the value returned by the function `op`.
- */
-pub fn from_fn<T>(n_elts: uint, op: |uint| -> T) -> ~[T] {
- unsafe {
- let mut v = with_capacity(n_elts);
- let p = raw::to_mut_ptr(v);
- let mut i: uint = 0u;
- (|| {
- while i < n_elts {
- intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), op(i));
- i += 1u;
- }
- }).finally(|| {
- raw::set_len(&mut v, i);
- });
- v
- }
-}
-
-/**
- * Creates and initializes an owned vector.
- *
- * Creates an owned vector of size `n_elts` and initializes the elements
- * to the value `t`.
- */
-pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
- // FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very
- // important, from_elem is a bottleneck in borrowck!). Unfortunately it
- // still is substantially slower than using the unsafe
- // vec::with_capacity/ptr::set_memory for primitive types.
- unsafe {
- let mut v = with_capacity(n_elts);
- let p = raw::to_mut_ptr(v);
- let mut i = 0u;
- (|| {
- while i < n_elts {
- intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), t.clone());
- i += 1u;
- }
- }).finally(|| {
- raw::set_len(&mut v, i);
- });
- v
- }
-}
-
-/// Creates a new vector with a capacity of `capacity`
-#[inline]
-pub fn with_capacity<T>(capacity: uint) -> ~[T] {
- unsafe {
- if owns_managed::<T>() {
- let mut vec = ~[];
- vec.reserve(capacity);
- vec
- } else {
- let alloc = capacity * mem::nonzero_size_of::<T>();
- let size = alloc + mem::size_of::<Vec<()>>();
- if alloc / mem::nonzero_size_of::<T>() != capacity || size < alloc {
- fail!("vector size is too large: {}", capacity);
- }
- let ptr = malloc_raw(size) as *mut Vec<()>;
- (*ptr).alloc = alloc;
- (*ptr).fill = 0;
- cast::transmute(ptr)
- }
- }
-}
-
-/**
- * Builds a vector by calling a provided function with an argument
- * function that pushes an element to the back of a vector.
- * The initial capacity for the vector may optionally be specified.
- *
- * # Arguments
- *
- * * size - An option, maybe containing initial size of the vector to reserve
- * * builder - A function that will construct the vector. It receives
- * as an argument a function that will push an element
- * onto the vector being constructed.
- */
-#[inline]
-pub fn build<A>(size: Option<uint>, builder: |push: |v: A||) -> ~[A] {
- let mut vec = with_capacity(size.unwrap_or(4));
- builder(|x| vec.push(x));
- vec
-}
-
-/// An iterator over the slices of a vector separated by elements that
-/// match a predicate function.
-pub struct SplitIterator<'self, T> {
- priv v: &'self [T],
- priv n: uint,
- priv pred: 'self |t: &T| -> bool,
- priv finished: bool
-}
-
-impl<'self, T> Iterator<&'self [T]> for SplitIterator<'self, T> {
- #[inline]
- fn next(&mut self) -> Option<&'self [T]> {
- if self.finished { return None; }
-
- if self.n == 0 {
- self.finished = true;
- return Some(self.v);
- }
-
- match self.v.iter().position(|x| (self.pred)(x)) {
- None => {
- self.finished = true;
- Some(self.v)
- }
- Some(idx) => {
- let ret = Some(self.v.slice(0, idx));
- self.v = self.v.slice(idx + 1, self.v.len());
- self.n -= 1;
- ret
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- if self.finished {
- return (0, Some(0))
- }
- // if the predicate doesn't match anything, we yield one slice
- // if it matches every element, we yield N+1 empty slices where
- // N is either the number of elements or the number of splits.
- match (self.v.len(), self.n) {
- (0,_) => (1, Some(1)),
- (_,0) => (1, Some(1)),
- (l,n) => (1, cmp::min(l,n).checked_add(&1u))
- }
- }
-}
-
-/// An iterator over the slices of a vector separated by elements that
-/// match a predicate function, from back to front.
-pub struct RSplitIterator<'self, T> {
- priv v: &'self [T],
- priv n: uint,
- priv pred: 'self |t: &T| -> bool,
- priv finished: bool
-}
-
-impl<'self, T> Iterator<&'self [T]> for RSplitIterator<'self, T> {
- #[inline]
- fn next(&mut self) -> Option<&'self [T]> {
- if self.finished { return None; }
-
- if self.n == 0 {
- self.finished = true;
- return Some(self.v);
- }
-
- match self.v.iter().rposition(|x| (self.pred)(x)) {
- None => {
- self.finished = true;
- Some(self.v)
- }
- Some(idx) => {
- let ret = Some(self.v.slice(idx + 1, self.v.len()));
- self.v = self.v.slice(0, idx);
- self.n -= 1;
- ret
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- if self.finished {
- return (0, Some(0))
- }
- match (self.v.len(), self.n) {
- (0,_) => (1, Some(1)),
- (_,0) => (1, Some(1)),
- (l,n) => (1, cmp::min(l,n).checked_add(&1u))
- }
- }
-}
-
-// Appending
-
-/// Iterates over the `rhs` vector, copying each element and appending it to the
-/// `lhs`. Afterwards, the `lhs` is then returned for use again.
-#[inline]
-pub fn append<T:Clone>(lhs: ~[T], rhs: &[T]) -> ~[T] {
- let mut v = lhs;
- v.push_all(rhs);
- v
-}
-
-/// Appends one element to the vector provided. The vector itself is then
-/// returned for use again.
-#[inline]
-pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
- let mut v = lhs;
- v.push(x);
- v
-}
-
-// Functional utilities
-
-/**
- * Apply a function to each element of a vector and return a concatenation
- * of each result vector
- */
-pub fn flat_map<T, U>(v: &[T], f: |t: &T| -> ~[U]) -> ~[U] {
- let mut result = ~[];
- for elem in v.iter() { result.push_all_move(f(elem)); }
- result
-}
-
-#[allow(missing_doc)]
-pub trait VectorVector<T> {
- // FIXME #5898: calling these .concat and .connect conflicts with
- // StrVector::con{cat,nect}, since they have generic contents.
- /// Flattens a vector of vectors of T into a single vector of T.
- fn concat_vec(&self) -> ~[T];
-
- /// Concatenate a vector of vectors, placing a given separator between each.
- fn connect_vec(&self, sep: &T) -> ~[T];
-}
-
-impl<'self, T: Clone, V: Vector<T>> VectorVector<T> for &'self [V] {
- fn concat_vec(&self) -> ~[T] {
- let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
- let mut result = with_capacity(size);
- for v in self.iter() {
- result.push_all(v.as_slice())
- }
- result
- }
-
- fn connect_vec(&self, sep: &T) -> ~[T] {
- let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
- let mut result = with_capacity(size + self.len());
- let mut first = true;
- for v in self.iter() {
- if first { first = false } else { result.push(sep.clone()) }
- result.push_all(v.as_slice())
- }
- result
- }
-}
-
-/**
- * Convert an iterator of pairs into a pair of vectors.
- *
- * Returns a tuple containing two vectors where the i-th element of the first
- * vector contains the first element of the i-th tuple of the input iterator,
- * and the i-th element of the second vector contains the second element
- * of the i-th tuple of the input iterator.
- */
-pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (~[T], ~[U]) {
- let (lo, _) = iter.size_hint();
- let mut ts = with_capacity(lo);
- let mut us = with_capacity(lo);
- for (t, u) in iter {
- ts.push(t);
- us.push(u);
- }
- (ts, us)
-}
-
-/// An Iterator that yields the element swaps needed to produce
-/// a sequence of all possible permutations for an indexed sequence of
-/// elements. Each permutation is only a single swap apart.
-///
-/// The Steinhaus–Johnson–Trotter algorithm is used.
-///
-/// Generates even and odd permutations alternatingly.
-///
-/// The last generated swap is always (0, 1), and it returns the
-/// sequence to its initial order.
-pub struct ElementSwaps {
- priv sdir: ~[SizeDirection],
- /// If true, emit the last swap that returns the sequence to initial state
- priv emit_reset: bool,
-}
-
-impl ElementSwaps {
- /// Create an `ElementSwaps` iterator for a sequence of `length` elements
- pub fn new(length: uint) -> ElementSwaps {
- // Initialize `sdir` with a direction that position should move in
- // (all negative at the beginning) and the `size` of the
- // element (equal to the original index).
- ElementSwaps{
- emit_reset: true,
- sdir: range(0, length)
- .map(|i| SizeDirection{ size: i, dir: Neg })
- .to_owned_vec()
- }
- }
-}
-
-enum Direction { Pos, Neg }
-
-/// An Index and Direction together
-struct SizeDirection {
- size: uint,
- dir: Direction,
-}
-
-impl Iterator<(uint, uint)> for ElementSwaps {
- #[inline]
- fn next(&mut self) -> Option<(uint, uint)> {
- fn new_pos(i: uint, s: Direction) -> uint {
- i + match s { Pos => 1, Neg => -1 }
- }
-
- // Find the index of the largest mobile element:
- // The direction should point into the vector, and the
- // swap should be with a smaller `size` element.
- let max = self.sdir.iter().map(|&x| x).enumerate()
- .filter(|&(i, sd)|
- new_pos(i, sd.dir) < self.sdir.len() &&
- self.sdir[new_pos(i, sd.dir)].size < sd.size)
- .max_by(|&(_, sd)| sd.size);
- match max {
- Some((i, sd)) => {
- let j = new_pos(i, sd.dir);
- self.sdir.swap(i, j);
-
- // Swap the direction of each larger SizeDirection
- for x in self.sdir.mut_iter() {
- if x.size > sd.size {
- x.dir = match x.dir { Pos => Neg, Neg => Pos };
- }
- }
- Some((i, j))
- },
- None => if self.emit_reset && self.sdir.len() > 1 {
- self.emit_reset = false;
- Some((0, 1))
- } else {
- None
- }
- }
- }
-}
-
-/// An Iterator that uses `ElementSwaps` to iterate through
-/// all possible permutations of a vector.
-///
-/// The first iteration yields a clone of the vector as it is,
-/// then each successive element is the vector with one
-/// swap applied.
-///
-/// Generates even and odd permutations alternatingly.
-pub struct Permutations<T> {
- priv swaps: ElementSwaps,
- priv v: ~[T],
-}
-
-impl<T: Clone> Iterator<~[T]> for Permutations<T> {
- #[inline]
- fn next(&mut self) -> Option<~[T]> {
- match self.swaps.next() {
- None => None,
- Some((a, b)) => {
- let elt = self.v.clone();
- self.v.swap(a, b);
- Some(elt)
- }
- }
- }
-}
-
-/// An iterator over the (overlapping) slices of length `size` within
-/// a vector.
-#[deriving(Clone)]
-pub struct WindowIter<'self, T> {
- priv v: &'self [T],
- priv size: uint
-}
-
-impl<'self, T> Iterator<&'self [T]> for WindowIter<'self, T> {
- #[inline]
- fn next(&mut self) -> Option<&'self [T]> {
- if self.size > self.v.len() {
- None
- } else {
- let ret = Some(self.v.slice(0, self.size));
- self.v = self.v.slice(1, self.v.len());
- ret
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- if self.size > self.v.len() {
- (0, Some(0))
- } else {
- let x = self.v.len() - self.size;
- (x.saturating_add(1), x.checked_add(&1u))
- }
- }
-}
-
-/// An iterator over a vector in (non-overlapping) chunks (`size`
-/// elements at a time).
-///
-/// When the vector len is not evenly divided by the chunk size,
-/// the last slice of the iteration will be the remainder.
-#[deriving(Clone)]
-pub struct ChunkIter<'self, T> {
- priv v: &'self [T],
- priv size: uint
-}
-
-impl<'self, T> Iterator<&'self [T]> for ChunkIter<'self, T> {
- #[inline]
- fn next(&mut self) -> Option<&'self [T]> {
- if self.v.len() == 0 {
- None
- } else {
- let chunksz = cmp::min(self.v.len(), self.size);
- let (fst, snd) = (self.v.slice_to(chunksz),
- self.v.slice_from(chunksz));
- self.v = snd;
- Some(fst)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- if self.v.len() == 0 {
- (0, Some(0))
- } else {
- let (n, rem) = self.v.len().div_rem(&self.size);
- let n = if rem > 0 { n+1 } else { n };
- (n, Some(n))
- }
- }
-}
-
-impl<'self, T> DoubleEndedIterator<&'self [T]> for ChunkIter<'self, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'self [T]> {
- if self.v.len() == 0 {
- None
- } else {
- let remainder = self.v.len() % self.size;
- let chunksz = if remainder != 0 { remainder } else { self.size };
- let (fst, snd) = (self.v.slice_to(self.v.len() - chunksz),
- self.v.slice_from(self.v.len() - chunksz));
- self.v = fst;
- Some(snd)
- }
- }
-}
-
-impl<'self, T> RandomAccessIterator<&'self [T]> for ChunkIter<'self, T> {
- #[inline]
- fn indexable(&self) -> uint {
- self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<&'self [T]> {
- if index < self.indexable() {
- let lo = index * self.size;
- let mut hi = lo + self.size;
- if hi < lo || hi > self.v.len() { hi = self.v.len(); }
-
- Some(self.v.slice(lo, hi))
- } else {
- None
- }
- }
-}
-
-// Equality
-
-#[cfg(not(test))]
-#[allow(missing_doc)]
-pub mod traits {
- use super::*;
-
- use clone::Clone;
- use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equiv};
- use iter::order;
- use ops::Add;
-
- impl<'self,T:Eq> Eq for &'self [T] {
- fn eq(&self, other: & &'self [T]) -> bool {
- self.len() == other.len() &&
- order::eq(self.iter(), other.iter())
- }
- fn ne(&self, other: & &'self [T]) -> bool {
- self.len() != other.len() ||
- order::ne(self.iter(), other.iter())
- }
- }
-
- impl<T:Eq> Eq for ~[T] {
- #[inline]
- fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other }
- #[inline]
- fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
- }
-
- impl<T:Eq> Eq for @[T] {
- #[inline]
- fn eq(&self, other: &@[T]) -> bool { self.as_slice() == *other }
- #[inline]
- fn ne(&self, other: &@[T]) -> bool { !self.eq(other) }
- }
-
- impl<'self,T:TotalEq> TotalEq for &'self [T] {
- fn equals(&self, other: & &'self [T]) -> bool {
- self.len() == other.len() &&
- order::equals(self.iter(), other.iter())
- }
- }
-
- impl<T:TotalEq> TotalEq for ~[T] {
- #[inline]
- fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
- }
-
- impl<T:TotalEq> TotalEq for @[T] {
- #[inline]
- fn equals(&self, other: &@[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
- }
-
- impl<'self,T:Eq, V: Vector<T>> Equiv<V> for &'self [T] {
- #[inline]
- fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
- }
-
- impl<'self,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
- #[inline]
- fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
- }
-
- impl<'self,T:Eq, V: Vector<T>> Equiv<V> for @[T] {
- #[inline]
- fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
- }
-
- impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
- fn cmp(&self, other: & &'self [T]) -> Ordering {
- order::cmp(self.iter(), other.iter())
- }
- }
-
- impl<T: TotalOrd> TotalOrd for ~[T] {
- #[inline]
- fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
- }
-
- impl<T: TotalOrd> TotalOrd for @[T] {
- #[inline]
- fn cmp(&self, other: &@[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
- }
-
- impl<'self, T: Eq + Ord> Ord for &'self [T] {
- fn lt(&self, other: & &'self [T]) -> bool {
- order::lt(self.iter(), other.iter())
- }
- #[inline]
- fn le(&self, other: & &'self [T]) -> bool {
- order::le(self.iter(), other.iter())
- }
- #[inline]
- fn ge(&self, other: & &'self [T]) -> bool {
- order::ge(self.iter(), other.iter())
- }
- #[inline]
- fn gt(&self, other: & &'self [T]) -> bool {
- order::gt(self.iter(), other.iter())
- }
- }
-
- impl<T: Eq + Ord> Ord for ~[T] {
- #[inline]
- fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
- #[inline]
- fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() }
- #[inline]
- fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() }
- #[inline]
- fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() }
- }
-
- impl<T: Eq + Ord> Ord for @[T] {
- #[inline]
- fn lt(&self, other: &@[T]) -> bool { self.as_slice() < other.as_slice() }
- #[inline]
- fn le(&self, other: &@[T]) -> bool { self.as_slice() <= other.as_slice() }
- #[inline]
- fn ge(&self, other: &@[T]) -> bool { self.as_slice() >= other.as_slice() }
- #[inline]
- fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() }
- }
-
- impl<'self,T:Clone, V: Vector<T>> Add<V, ~[T]> for &'self [T] {
- #[inline]
- fn add(&self, rhs: &V) -> ~[T] {
- let mut res = with_capacity(self.len() + rhs.as_slice().len());
- res.push_all(*self);
- res.push_all(rhs.as_slice());
- res
- }
- }
-
- impl<T:Clone, V: Vector<T>> Add<V, ~[T]> for ~[T] {
- #[inline]
- fn add(&self, rhs: &V) -> ~[T] {
- self.as_slice() + rhs.as_slice()
- }
- }
-}
-
-#[cfg(test)]
-pub mod traits {}
-
-/// Any vector that can be represented as a slice.
-pub trait Vector<T> {
- /// Work with `self` as a slice.
- fn as_slice<'a>(&'a self) -> &'a [T];
-}
-
-impl<'self,T> Vector<T> for &'self [T] {
- #[inline(always)]
- fn as_slice<'a>(&'a self) -> &'a [T] { *self }
-}
-
-impl<T> Vector<T> for ~[T] {
- #[inline(always)]
- fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
-}
-
-impl<T> Vector<T> for @[T] {
- #[inline(always)]
- fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
-}
-
-impl<'self, T> Container for &'self [T] {
- /// Returns the length of a vector
- #[inline]
- fn len(&self) -> uint {
- self.as_imm_buf(|_p, len| len)
- }
-}
-
-impl<T> Container for ~[T] {
- /// Returns the length of a vector
- #[inline]
- fn len(&self) -> uint {
- self.as_imm_buf(|_p, len| len)
- }
-}
-
-/// Extension methods for vector slices with copyable elements
-pub trait CopyableVector<T> {
- /// Copy `self` into a new owned vector
- fn to_owned(&self) -> ~[T];
-
- /// Convert `self` into a owned vector, not making a copy if possible.
- fn into_owned(self) -> ~[T];
-}
-
-/// Extension methods for vector slices
-impl<'self, T: Clone> CopyableVector<T> for &'self [T] {
- /// Returns a copy of `v`.
- #[inline]
- fn to_owned(&self) -> ~[T] {
- let mut result = with_capacity(self.len());
- for e in self.iter() {
- result.push((*e).clone());
- }
- result
- }
-
- #[inline(always)]
- fn into_owned(self) -> ~[T] { self.to_owned() }
-}
-
-/// Extension methods for owned vectors
-impl<T: Clone> CopyableVector<T> for ~[T] {
- #[inline]
- fn to_owned(&self) -> ~[T] { self.clone() }
-
- #[inline(always)]
- fn into_owned(self) -> ~[T] { self }
-}
-
-/// Extension methods for managed vectors
-impl<T: Clone> CopyableVector<T> for @[T] {
- #[inline]
- fn to_owned(&self) -> ~[T] { self.as_slice().to_owned() }
-
- #[inline(always)]
- fn into_owned(self) -> ~[T] { self.to_owned() }
-}
-
-/// Extension methods for vectors
-pub trait ImmutableVector<'self, T> {
- /**
- * Returns a slice of self between `start` and `end`.
- *
- * Fails when `start` or `end` point outside the bounds of self,
- * or when `start` > `end`.
- */
- fn slice(&self, start: uint, end: uint) -> &'self [T];
-
- /**
- * Returns a slice of self from `start` to the end of the vec.
- *
- * Fails when `start` points outside the bounds of self.
- */
- fn slice_from(&self, start: uint) -> &'self [T];
-
- /**
- * Returns a slice of self from the start of the vec to `end`.
- *
- * Fails when `end` points outside the bounds of self.
- */
- fn slice_to(&self, end: uint) -> &'self [T];
- /// Returns an iterator over the vector
- fn iter(self) -> VecIterator<'self, T>;
- /// Returns a reversed iterator over a vector
- fn rev_iter(self) -> RevIterator<'self, T>;
- /// Returns an iterator over the subslices of the vector which are
- /// separated by elements that match `pred`.
- fn split(self, pred: 'self |&T| -> bool) -> SplitIterator<'self, T>;
- /// Returns an iterator over the subslices of the vector which are
- /// separated by elements that match `pred`, limited to splitting
- /// at most `n` times.
- fn splitn(self, n: uint, pred: 'self |&T| -> bool) -> SplitIterator<'self, T>;
- /// Returns an iterator over the subslices of the vector which are
- /// separated by elements that match `pred`. This starts at the
- /// end of the vector and works backwards.
- fn rsplit(self, pred: 'self |&T| -> bool) -> RSplitIterator<'self, T>;
- /// Returns an iterator over the subslices of the vector which are
- /// separated by elements that match `pred` limited to splitting
- /// at most `n` times. This starts at the end of the vector and
- /// works backwards.
- fn rsplitn(self, n: uint, pred: 'self |&T| -> bool) -> RSplitIterator<'self, T>;
-
- /**
- * Returns an iterator over all contiguous windows of length
- * `size`. The windows overlap. If the vector is shorter than
- * `size`, the iterator returns no values.
- *
- * # Failure
- *
- * Fails if `size` is 0.
- *
- * # Example
- *
- * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`,
- * `[3,4]`):
- *
- * ```rust
- * let v = &[1,2,3,4];
- * for win in v.windows(2) {
- * println!("{:?}", win);
- * }
- * ```
- *
- */
- fn windows(self, size: uint) -> WindowIter<'self, T>;
- /**
- *
- * Returns an iterator over `size` elements of the vector at a
- * time. The chunks do not overlap. If `size` does not divide the
- * length of the vector, then the last chunk will not have length
- * `size`.
- *
- * # Failure
- *
- * Fails if `size` is 0.
- *
- * # Example
- *
- * Print the vector two elements at a time (i.e. `[1,2]`,
- * `[3,4]`, `[5]`):
- *
- * ```rust
- * let v = &[1,2,3,4,5];
- * for win in v.chunks(2) {
- * println!("{:?}", win);
- * }
- * ```
- *
- */
- fn chunks(self, size: uint) -> ChunkIter<'self, T>;
-
- /// Returns the element of a vector at the given index, or `None` if the
- /// index is out of bounds
- fn get_opt(&self, index: uint) -> Option<&'self T>;
- /// Returns the first element of a vector, failing if the vector is empty.
- fn head(&self) -> &'self T;
- /// Returns the first element of a vector, or `None` if it is empty
- fn head_opt(&self) -> Option<&'self T>;
- /// Returns all but the first element of a vector
- fn tail(&self) -> &'self [T];
- /// Returns all but the first `n' elements of a vector
- fn tailn(&self, n: uint) -> &'self [T];
- /// Returns all but the last element of a vector
- fn init(&self) -> &'self [T];
- /// Returns all but the last `n' elemnts of a vector
- fn initn(&self, n: uint) -> &'self [T];
- /// Returns the last element of a vector, failing if the vector is empty.
- fn last(&self) -> &'self T;
- /// Returns the last element of a vector, or `None` if it is empty.
- fn last_opt(&self) -> Option<&'self T>;
- /**
- * Apply a function to each element of a vector and return a concatenation
- * of each result vector
- */
- fn flat_map<U>(&self, f: |t: &T| -> ~[U]) -> ~[U];
- /// Returns a pointer to the element at the given index, without doing
- /// bounds checking.
- unsafe fn unsafe_ref(&self, index: uint) -> *T;
-
- /**
- * Binary search a sorted vector with a comparator function.
- *
- * The comparator should implement an order consistent with the sort
- * order of the underlying vector, returning an order code that indicates
- * whether its argument is `Less`, `Equal` or `Greater` the desired target.
- *
- * Returns the index where the comparator returned `Equal`, or `None` if
- * not found.
- */
- fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint>;
-
- /// Deprecated, use iterators where possible
- /// (`self.iter().map(f)`). Apply a function to each element
- /// of a vector and return the results.
- fn map<U>(&self, |t: &T| -> U) -> ~[U];
-
- /**
- * Work with the buffer of a vector.
- *
- * Allows for unsafe manipulation of vector contents, which is useful for
- * foreign interop.
- */
- fn as_imm_buf<U>(&self, f: |*T, uint| -> U) -> U;
-
- /**
- * Returns a mutable reference to the first element in this slice
- * and adjusts the slice in place so that it no longer contains
- * that element. O(1).
- *
- * Equivalent to:
- *
- * ```
- * let head = &self[0];
- * *self = self.slice_from(1);
- * head
- * ```
- *
- * Fails if slice is empty.
- */
- fn shift_ref(&mut self) -> &'self T;
-
- /**
- * Returns a mutable reference to the last element in this slice
- * and adjusts the slice in place so that it no longer contains
- * that element. O(1).
- *
- * Equivalent to:
- *
- * ```
- * let tail = &self[self.len() - 1];
- * *self = self.slice_to(self.len() - 1);
- * tail
- * ```
- *
- * Fails if slice is empty.
- */
- fn pop_ref(&mut self) -> &'self T;
-}
-
-impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
- #[inline]
- fn slice(&self, start: uint, end: uint) -> &'self [T] {
- assert!(start <= end);
- assert!(end <= self.len());
- self.as_imm_buf(|p, _len| {
- unsafe {
- cast::transmute(Slice {
- data: ptr::offset(p, start as int),
- len: (end - start)
- })
- }
- })
- }
-
- #[inline]
- fn slice_from(&self, start: uint) -> &'self [T] {
- self.slice(start, self.len())
- }
-
- #[inline]
- fn slice_to(&self, end: uint) -> &'self [T] {
- self.slice(0, end)
- }
-
- #[inline]
- fn iter(self) -> VecIterator<'self, T> {
- unsafe {
- let p = vec::raw::to_ptr(self);
- if mem::size_of::<T>() == 0 {
- VecIterator{ptr: p,
- end: (p as uint + self.len()) as *T,
- lifetime: None}
- } else {
- VecIterator{ptr: p,
- end: p.offset(self.len() as int),
- lifetime: None}
- }
- }
- }
-
- #[inline]
- fn rev_iter(self) -> RevIterator<'self, T> {
- self.iter().invert()
- }
-
- #[inline]
- fn split(self, pred: 'self |&T| -> bool) -> SplitIterator<'self, T> {
- self.splitn(uint::max_value, pred)
- }
-
- #[inline]
- fn splitn(self, n: uint, pred: 'self |&T| -> bool) -> SplitIterator<'self, T> {
- SplitIterator {
- v: self,
- n: n,
- pred: pred,
- finished: false
- }
- }
-
- #[inline]
- fn rsplit(self, pred: 'self |&T| -> bool) -> RSplitIterator<'self, T> {
- self.rsplitn(uint::max_value, pred)
- }
-
- #[inline]
- fn rsplitn(self, n: uint, pred: 'self |&T| -> bool) -> RSplitIterator<'self, T> {
- RSplitIterator {
- v: self,
- n: n,
- pred: pred,
- finished: false
- }
- }
-
- #[inline]
- fn windows(self, size: uint) -> WindowIter<'self, T> {
- assert!(size != 0);
- WindowIter { v: self, size: size }
- }
-
- #[inline]
- fn chunks(self, size: uint) -> ChunkIter<'self, T> {
- assert!(size != 0);
- ChunkIter { v: self, size: size }
- }
-
- #[inline]
- fn get_opt(&self, index: uint) -> Option<&'self T> {
- if index < self.len() { Some(&self[index]) } else { None }
- }
-
- #[inline]
- fn head(&self) -> &'self T {
- if self.len() == 0 { fail!("head: empty vector") }
- &self[0]
- }
-
- #[inline]
- fn head_opt(&self) -> Option<&'self T> {
- if self.len() == 0 { None } else { Some(&self[0]) }
- }
-
- #[inline]
- fn tail(&self) -> &'self [T] { self.slice(1, self.len()) }
-
- #[inline]
- fn tailn(&self, n: uint) -> &'self [T] { self.slice(n, self.len()) }
-
- #[inline]
- fn init(&self) -> &'self [T] {
- self.slice(0, self.len() - 1)
- }
-
- #[inline]
- fn initn(&self, n: uint) -> &'self [T] {
- self.slice(0, self.len() - n)
- }
-
- #[inline]
- fn last(&self) -> &'self T {
- if self.len() == 0 { fail!("last: empty vector") }
- &self[self.len() - 1]
- }
-
- #[inline]
- fn last_opt(&self) -> Option<&'self T> {
- if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
- }
-
- #[inline]
- fn flat_map<U>(&self, f: |t: &T| -> ~[U]) -> ~[U] {
- flat_map(*self, f)
- }
-
- #[inline]
- unsafe fn unsafe_ref(&self, index: uint) -> *T {
- self.repr().data.offset(index as int)
- }
-
- fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint> {
- let mut base : uint = 0;
- let mut lim : uint = self.len();
-
- while lim != 0 {
- let ix = base + (lim >> 1);
- match f(&self[ix]) {
- Equal => return Some(ix),
- Less => {
- base = ix + 1;
- lim -= 1;
- }
- Greater => ()
- }
- lim >>= 1;
- }
- return None;
- }
-
- fn map<U>(&self, f: |t: &T| -> U) -> ~[U] {
- self.iter().map(f).collect()
- }
-
- #[inline]
- fn as_imm_buf<U>(&self, f: |*T, uint| -> U) -> U {
- let s = self.repr();
- f(s.data, s.len)
- }
-
- fn shift_ref(&mut self) -> &'self T {
- unsafe {
- let s: &mut Slice<T> = cast::transmute(self);
- &*raw::shift_ptr(s)
- }
- }
-
- fn pop_ref(&mut self) -> &'self T {
- unsafe {
- let s: &mut Slice<T> = cast::transmute(self);
- &*raw::pop_ptr(s)
- }
- }
-}
-
-/// Extension methods for vectors contain `Eq` elements.
-pub trait ImmutableEqVector<T:Eq> {
- /// Find the first index containing a matching value
- fn position_elem(&self, t: &T) -> Option<uint>;
-
- /// Find the last index containing a matching value
- fn rposition_elem(&self, t: &T) -> Option<uint>;
-
- /// Return true if a vector contains an element with the given value
- fn contains(&self, x: &T) -> bool;
-
- /// Returns true if `needle` is a prefix of the vector.
- fn starts_with(&self, needle: &[T]) -> bool;
-
- /// Returns true if `needle` is a suffix of the vector.
- fn ends_with(&self, needle: &[T]) -> bool;
-}
-
-impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
- #[inline]
- fn position_elem(&self, x: &T) -> Option<uint> {
- self.iter().position(|y| *x == *y)
- }
-
- #[inline]
- fn rposition_elem(&self, t: &T) -> Option<uint> {
- self.iter().rposition(|x| *x == *t)
- }
-
- #[inline]
- fn contains(&self, x: &T) -> bool {
- self.iter().any(|elt| *x == *elt)
- }
-
- #[inline]
- fn starts_with(&self, needle: &[T]) -> bool {
- let n = needle.len();
- self.len() >= n && needle == self.slice_to(n)
- }
-
- #[inline]
- fn ends_with(&self, needle: &[T]) -> bool {
- let (m, n) = (self.len(), needle.len());
- m >= n && needle == self.slice_from(m - n)
- }
-}
-
-/// Extension methods for vectors containing `TotalOrd` elements.
-pub trait ImmutableTotalOrdVector<T: TotalOrd> {
- /**
- * Binary search a sorted vector for a given element.
- *
- * Returns the index of the element or None if not found.
- */
- fn bsearch_elem(&self, x: &T) -> Option<uint>;
-}
-
-impl<'self, T: TotalOrd> ImmutableTotalOrdVector<T> for &'self [T] {
- fn bsearch_elem(&self, x: &T) -> Option<uint> {
- self.bsearch(|p| p.cmp(x))
- }
-}
-
-/// Extension methods for vectors containing `Clone` elements.
-pub trait ImmutableCopyableVector<T> {
- /**
- * Partitions the vector into those that satisfies the predicate, and
- * those that do not.
- */
- fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]);
- /// Returns the element at the given index, without doing bounds checking.
- unsafe fn unsafe_get(&self, elem: uint) -> T;
-
- /// Create an iterator that yields every possible permutation of the
- /// vector in succession.
- fn permutations(self) -> Permutations<T>;
-}
-
-impl<'self,T:Clone> ImmutableCopyableVector<T> for &'self [T] {
- #[inline]
- fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
- let mut lefts = ~[];
- let mut rights = ~[];
-
- for elt in self.iter() {
- if f(elt) {
- lefts.push((*elt).clone());
- } else {
- rights.push((*elt).clone());
- }
- }
-
- (lefts, rights)
- }
-
- #[inline]
- unsafe fn unsafe_get(&self, index: uint) -> T {
- (*self.unsafe_ref(index)).clone()
- }
-
- fn permutations(self) -> Permutations<T> {
- Permutations{
- swaps: ElementSwaps::new(self.len()),
- v: self.to_owned(),
- }
- }
-
-}
-
-/// Extension methods for owned vectors.
-pub trait OwnedVector<T> {
- /// Creates a consuming iterator, that is, one that moves each
- /// value out of the vector (from start to end). The vector cannot
- /// be used after calling this.
- ///
- /// Note that this performs O(n) swaps, and so `move_rev_iter`
- /// (which just calls `pop` repeatedly) is more efficient.
- ///
- /// # Examples
- ///
- /// ```rust
- /// let v = ~[~"a", ~"b"];
- /// for s in v.move_iter() {
- /// // s has type ~str, not &~str
- /// println(s);
- /// }
- /// ```
- fn move_iter(self) -> MoveIterator<T>;
- /// Creates a consuming iterator that moves out of the vector in
- /// reverse order. Also see `move_iter`, however note that this
- /// is more efficient.
- fn move_rev_iter(self) -> MoveRevIterator<T>;
-
- /**
- * Reserves capacity for exactly `n` elements in the given vector.
- *
- * If the capacity for `self` is already equal to or greater than the requested
- * capacity, then no action is taken.
- *
- * # Arguments
- *
- * * n - The number of elements to reserve space for
- *
- * # Failure
- *
- * This method always succeeds in reserving space for `n` elements, or it does
- * not return.
- */
- fn reserve(&mut self, n: uint);
- /**
- * Reserves capacity for at least `n` elements in the given vector.
- *
- * This function will over-allocate in order to amortize the allocation costs
- * in scenarios where the caller may need to repeatedly reserve additional
- * space.
- *
- * If the capacity for `self` is already equal to or greater than the requested
- * capacity, then no action is taken.
- *
- * # Arguments
- *
- * * n - The number of elements to reserve space for
- */
- fn reserve_at_least(&mut self, n: uint);
- /**
- * Reserves capacity for at least `n` additional elements in the given vector.
- *
- * # Failure
- *
- * Fails if the new required capacity overflows uint.
- *
- * May also fail if `reserve` fails.
- */
- fn reserve_additional(&mut self, n: uint);
- /// Returns the number of elements the vector can hold without reallocating.
- fn capacity(&self) -> uint;
- /// Shrink the capacity of the vector to match the length
- fn shrink_to_fit(&mut self);
-
- /// Append an element to a vector
- fn push(&mut self, t: T);
- /// Takes ownership of the vector `rhs`, moving all elements into
- /// the current vector. This does not copy any elements, and it is
- /// illegal to use the `rhs` vector after calling this method
- /// (because it is moved here).
- ///
- /// # Example
- ///
- /// ```rust
- /// let mut a = ~[~1];
- /// a.push_all_move(~[~2, ~3, ~4]);
- /// assert!(a == ~[~1, ~2, ~3, ~4]);
- /// ```
- fn push_all_move(&mut self, rhs: ~[T]);
- /// Remove the last element from a vector and return it, failing if it is empty
- fn pop(&mut self) -> T;
- /// Remove the last element from a vector and return it, or `None` if it is empty
- fn pop_opt(&mut self) -> Option<T>;
- /// Removes the first element from a vector and return it
- fn shift(&mut self) -> T;
- /// Removes the first element from a vector and return it, or `None` if it is empty
- fn shift_opt(&mut self) -> Option<T>;
- /// Prepend an element to the vector
- fn unshift(&mut self, x: T);
-
- /// Insert an element at position i within v, shifting all
- /// elements after position i one position to the right.
- fn insert(&mut self, i: uint, x:T);
-
- /// Remove and return the element at position i within v, shifting
- /// all elements after position i one position to the left.
- fn remove(&mut self, i: uint) -> T;
-
- /**
- * Remove an element from anywhere in the vector and return it, replacing it
- * with the last element. This does not preserve ordering, but is O(1).
- *
- * Fails if index >= length.
- */
- fn swap_remove(&mut self, index: uint) -> T;
-
- /// Shorten a vector, dropping excess elements.
- fn truncate(&mut self, newlen: uint);
-
- /**
- * Like `filter()`, but in place. Preserves order of `v`. Linear time.
- */
- fn retain(&mut self, f: |t: &T| -> bool);
- /**
- * Partitions the vector into those that satisfies the predicate, and
- * those that do not.
- */
- fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]);
-
- /**
- * Expands a vector in place, initializing the new elements to the result of
- * a function
- *
- * Function `init_op` is called `n` times with the values [0..`n`)
- *
- * # Arguments
- *
- * * n - The number of elements to add
- * * init_op - A function to call to retreive each appended element's
- * value
- */
- fn grow_fn(&mut self, n: uint, op: |uint| -> T);
-}
-
-impl<T> OwnedVector<T> for ~[T] {
- fn move_iter(self) -> MoveIterator<T> {
- MoveIterator { v: self, idx: 0 }
- }
- fn move_rev_iter(self) -> MoveRevIterator<T> {
- MoveRevIterator { v: self }
- }
-
- fn reserve(&mut self, n: uint) {
- // Only make the (slow) call into the runtime if we have to
- if self.capacity() < n {
- unsafe {
- let td = get_tydesc::<T>();
- if owns_managed::<T>() {
- let ptr: *mut *mut Box<Vec<()>> = cast::transmute(self);
- ::at_vec::raw::reserve_raw(td, ptr, n);
- } else {
- let ptr: *mut *mut Vec<()> = cast::transmute(self);
- let alloc = n * mem::nonzero_size_of::<T>();
- let size = alloc + mem::size_of::<Vec<()>>();
- if alloc / mem::nonzero_size_of::<T>() != n || size < alloc {
- fail!("vector size is too large: {}", n);
- }
- *ptr = realloc_raw(*ptr as *mut c_void, size)
- as *mut Vec<()>;
- (**ptr).alloc = alloc;
- }
- }
- }
- }
-
- #[inline]
- fn reserve_at_least(&mut self, n: uint) {
- self.reserve(uint::next_power_of_two_opt(n).unwrap_or(n));
- }
-
- #[inline]
- fn reserve_additional(&mut self, n: uint) {
- if self.capacity() - self.len() < n {
- match self.len().checked_add(&n) {
- None => fail!("vec::reserve_additional: `uint` overflow"),
- Some(new_cap) => self.reserve_at_least(new_cap)
- }
- }
- }
-
- #[inline]
- fn capacity(&self) -> uint {
- unsafe {
- if owns_managed::<T>() {
- let repr: **Box<Vec<()>> = cast::transmute(self);
- (**repr).data.alloc / mem::nonzero_size_of::<T>()
- } else {
- let repr: **Vec<()> = cast::transmute(self);
- (**repr).alloc / mem::nonzero_size_of::<T>()
- }
- }
- }
-
- fn shrink_to_fit(&mut self) {
- unsafe {
- let ptr: *mut *mut Vec<()> = cast::transmute(self);
- let alloc = (**ptr).fill;
- let size = alloc + mem::size_of::<Vec<()>>();
- *ptr = realloc_raw(*ptr as *mut c_void, size) as *mut Vec<()>;
- (**ptr).alloc = alloc;
- }
- }
-
- #[inline]
- fn push(&mut self, t: T) {
- unsafe {
- if owns_managed::<T>() {
- let repr: **Box<Vec<()>> = cast::transmute(&mut *self);
- let fill = (**repr).data.fill;
- if (**repr).data.alloc <= fill {
- self.reserve_additional(1);
- }
-
- push_fast(self, t);
- } else {
- let repr: **Vec<()> = cast::transmute(&mut *self);
- let fill = (**repr).fill;
- if (**repr).alloc <= fill {
- self.reserve_additional(1);
- }
-
- push_fast(self, t);
- }
- }
-
- // This doesn't bother to make sure we have space.
- #[inline] // really pretty please
- unsafe fn push_fast<T>(this: &mut ~[T], t: T) {
- if owns_managed::<T>() {
- let repr: **mut Box<Vec<u8>> = cast::transmute(this);
- let fill = (**repr).data.fill;
- (**repr).data.fill += mem::nonzero_size_of::<T>();
- let p = to_unsafe_ptr(&((**repr).data.data));
- let p = ptr::offset(p, fill as int) as *mut T;
- intrinsics::move_val_init(&mut(*p), t);
- } else {
- let repr: **mut Vec<u8> = cast::transmute(this);
- let fill = (**repr).fill;
- (**repr).fill += mem::nonzero_size_of::<T>();
- let p = to_unsafe_ptr(&((**repr).data));
- let p = ptr::offset(p, fill as int) as *mut T;
- intrinsics::move_val_init(&mut(*p), t);
- }
- }
-
- }
-
- #[inline]
- fn push_all_move(&mut self, mut rhs: ~[T]) {
- let self_len = self.len();
- let rhs_len = rhs.len();
- let new_len = self_len + rhs_len;
- self.reserve_additional(rhs.len());
- unsafe { // Note: infallible.
- let self_p = vec::raw::to_mut_ptr(*self);
- let rhs_p = vec::raw::to_ptr(rhs);
- ptr::copy_memory(ptr::mut_offset(self_p, self_len as int), rhs_p, rhs_len);
- raw::set_len(self, new_len);
- raw::set_len(&mut rhs, 0);
- }
- }
-
- fn pop_opt(&mut self) -> Option<T> {
- match self.len() {
- 0 => None,
- ln => {
- let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]);
- unsafe {
- raw::set_len(self, ln - 1u);
- Some(ptr::read_ptr(&*valptr))
- }
- }
- }
- }
-
-
- #[inline]
- fn pop(&mut self) -> T {
- self.pop_opt().expect("pop: empty vector")
- }
-
- #[inline]
- fn shift(&mut self) -> T {
- self.shift_opt().expect("shift: empty vector")
- }
-
- fn shift_opt(&mut self) -> Option<T> {
- unsafe {
- let ln = match self.len() {
- 0 => return None,
- 1 => return self.pop_opt(),
- 2 => {
- let last = self.pop();
- let first = self.pop_opt();
- self.push(last);
- return first;
- }
- x => x
- };
-
- let next_ln = self.len() - 1;
-
- // Save the last element. We're going to overwrite its position
- let work_elt = self.pop();
- // We still should have room to work where what last element was
- assert!(self.capacity() >= ln);
- // Pretend like we have the original length so we can use
- // the vector copy_memory to overwrite the hole we just made
- raw::set_len(self, ln);
-
- // Memcopy the head element (the one we want) to the location we just
- // popped. For the moment it unsafely exists at both the head and last
- // positions
- {
- let first_slice = self.slice(0, 1);
- let last_slice = self.slice(next_ln, ln);
- raw::copy_memory(cast::transmute(last_slice), first_slice, 1);
- }
-
- // Memcopy everything to the left one element
- {
- let init_slice = self.slice(0, next_ln);
- let tail_slice = self.slice(1, ln);
- raw::copy_memory(cast::transmute(init_slice),
- tail_slice,
- next_ln);
- }
-
- // Set the new length. Now the vector is back to normal
- raw::set_len(self, next_ln);
-
- // Swap out the element we want from the end
- let vp = raw::to_mut_ptr(*self);
- let vp = ptr::mut_offset(vp, (next_ln - 1) as int);
-
- Some(ptr::replace_ptr(vp, work_elt))
- }
- }
-
- fn unshift(&mut self, x: T) {
- let v = util::replace(self, ~[x]);
- self.push_all_move(v);
- }
- fn insert(&mut self, i: uint, x:T) {
- let len = self.len();
- assert!(i <= len);
-
- self.push(x);
- let mut j = len;
- while j > i {
- self.swap(j, j - 1);
- j -= 1;
- }
- }
- fn remove(&mut self, i: uint) -> T {
- let len = self.len();
- assert!(i < len);
-
- let mut j = i;
- while j < len - 1 {
- self.swap(j, j + 1);
- j += 1;
- }
- self.pop()
- }
- fn swap_remove(&mut self, index: uint) -> T {
- let ln = self.len();
- if index >= ln {
- fail!("vec::swap_remove - index {} >= length {}", index, ln);
- }
- if index < ln - 1 {
- self.swap(index, ln - 1);
- }
- self.pop()
- }
- fn truncate(&mut self, newlen: uint) {
- self.as_mut_buf(|p, oldlen| {
- assert!(newlen <= oldlen);
- unsafe {
- // This loop is optimized out for non-drop types.
- for i in range(newlen, oldlen) {
- ptr::read_and_zero_ptr(ptr::mut_offset(p, i as int));
- }
- }
- });
- unsafe { raw::set_len(self, newlen); }
- }
-
- fn retain(&mut self, f: |t: &T| -> bool) {
- let len = self.len();
- let mut deleted: uint = 0;
-
- for i in range(0u, len) {
- if !f(&self[i]) {
- deleted += 1;
- } else if deleted > 0 {
- self.swap(i - deleted, i);
- }
- }
-
- if deleted > 0 {
- self.truncate(len - deleted);
- }
- }
-
- #[inline]
- fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
- let mut lefts = ~[];
- let mut rights = ~[];
-
- for elt in self.move_iter() {
- if f(&elt) {
- lefts.push(elt);
- } else {
- rights.push(elt);
- }
- }
-
- (lefts, rights)
- }
- fn grow_fn(&mut self, n: uint, op: |uint| -> T) {
- let new_len = self.len() + n;
- self.reserve_at_least(new_len);
- let mut i: uint = 0u;
- while i < n {
- self.push(op(i));
- i += 1u;
- }
- }
-}
-
-impl<T> Mutable for ~[T] {
- /// Clear the vector, removing all values.
- fn clear(&mut self) { self.truncate(0) }
-}
-
-/// Extension methods for owned vectors containing `Clone` elements.
-pub trait OwnedCopyableVector<T:Clone> {
- /// Iterates over the slice `rhs`, copies each element, and then appends it to
- /// the vector provided `v`. The `rhs` vector is traversed in-order.
- ///
- /// # Example
- ///
- /// ```rust
- /// let mut a = ~[1];
- /// a.push_all([2, 3, 4]);
- /// assert!(a == ~[1, 2, 3, 4]);
- /// ```
- fn push_all(&mut self, rhs: &[T]);
-
- /**
- * Expands a vector in place, initializing the new elements to a given value
- *
- * # Arguments
- *
- * * n - The number of elements to add
- * * initval - The value for the new elements
- */
- fn grow(&mut self, n: uint, initval: &T);
-
- /**
- * Sets the value of a vector element at a given index, growing the vector as
- * needed
- *
- * Sets the element at position `index` to `val`. If `index` is past the end
- * of the vector, expands the vector by replicating `initval` to fill the
- * intervening space.
- */
- fn grow_set(&mut self, index: uint, initval: &T, val: T);
-}
-
-impl<T:Clone> OwnedCopyableVector<T> for ~[T] {
- #[inline]
- fn push_all(&mut self, rhs: &[T]) {
- let new_len = self.len() + rhs.len();
- self.reserve(new_len);
-
- for elt in rhs.iter() {
- self.push((*elt).clone())
- }
- }
- fn grow(&mut self, n: uint, initval: &T) {
- let new_len = self.len() + n;
- self.reserve_at_least(new_len);
- let mut i: uint = 0u;
-
- while i < n {
- self.push((*initval).clone());
- i += 1u;
- }
- }
- fn grow_set(&mut self, index: uint, initval: &T, val: T) {
- let l = self.len();
- if index >= l { self.grow(index - l + 1u, initval); }
- self[index] = val;
- }
-}
-
-/// Extension methods for owned vectors containing `Eq` elements.
-pub trait OwnedEqVector<T:Eq> {
- /**
- * Remove consecutive repeated elements from a vector; if the vector is
- * sorted, this removes all duplicates.
- */
- fn dedup(&mut self);
-}
-
-impl<T:Eq> OwnedEqVector<T> for ~[T] {
- fn dedup(&mut self) {
- unsafe {
- // Although we have a mutable reference to `self`, we cannot make
- // *arbitrary* changes. There exists the possibility that this
- // vector is contained with an `@mut` box and hence is still
- // readable by the outside world during the `Eq` comparisons.
- // Moreover, those comparisons could fail, so we must ensure
- // that the vector is in a valid state at all time.
- //
- // The way that we handle this is by using swaps; we iterate
- // over all the elements, swapping as we go so that at the end
- // the elements we wish to keep are in the front, and those we
- // wish to reject are at the back. We can then truncate the
- // vector. This operation is still O(n).
- //
- // Example: We start in this state, where `r` represents "next
- // read" and `w` represents "next_write`.
- //
- // r
- // +---+---+---+---+---+---+
- // | 0 | 1 | 1 | 2 | 3 | 3 |
- // +---+---+---+---+---+---+
- // w
- //
- // Comparing self[r] against self[w-1], tis is not a duplicate, so
- // we swap self[r] and self[w] (no effect as r==w) and then increment both
- // r and w, leaving us with:
- //
- // r
- // +---+---+---+---+---+---+
- // | 0 | 1 | 1 | 2 | 3 | 3 |
- // +---+---+---+---+---+---+
- // w
- //
- // Comparing self[r] against self[w-1], this value is a duplicate,
- // so we increment `r` but leave everything else unchanged:
- //
- // r
- // +---+---+---+---+---+---+
- // | 0 | 1 | 1 | 2 | 3 | 3 |
- // +---+---+---+---+---+---+
- // w
- //
- // Comparing self[r] against self[w-1], this is not a duplicate,
- // so swap self[r] and self[w] and advance r and w:
- //
- // r
- // +---+---+---+---+---+---+
- // | 0 | 1 | 2 | 1 | 3 | 3 |
- // +---+---+---+---+---+---+
- // w
- //
- // Not a duplicate, repeat:
- //
- // r
- // +---+---+---+---+---+---+
- // | 0 | 1 | 2 | 3 | 1 | 3 |
- // +---+---+---+---+---+---+
- // w
- //
- // Duplicate, advance r. End of vec. Truncate to w.
-
- let ln = self.len();
- if ln < 1 { return; }
-
- // Avoid bounds checks by using unsafe pointers.
- let p = vec::raw::to_mut_ptr(*self);
- let mut r = 1;
- let mut w = 1;
-
- while r < ln {
- let p_r = ptr::mut_offset(p, r as int);
- let p_wm1 = ptr::mut_offset(p, (w - 1) as int);
- if *p_r != *p_wm1 {
- if r != w {
- let p_w = ptr::mut_offset(p_wm1, 1);
- util::swap(&mut *p_r, &mut *p_w);
- }
- w += 1;
- }
- r += 1;
- }
-
- self.truncate(w);
- }
- }
-}
-
-/// Extension methods for vectors such that their elements are
-/// mutable.
-pub trait MutableVector<'self, T> {
- /// Return a slice that points into another slice.
- fn mut_slice(self, start: uint, end: uint) -> &'self mut [T];
-
- /**
- * Returns a slice of self from `start` to the end of the vec.
- *
- * Fails when `start` points outside the bounds of self.
- */
- fn mut_slice_from(self, start: uint) -> &'self mut [T];
-
- /**
- * Returns a slice of self from the start of the vec to `end`.
- *
- * Fails when `end` points outside the bounds of self.
- */
- fn mut_slice_to(self, end: uint) -> &'self mut [T];
-
- /// Returns an iterator that allows modifying each value
- fn mut_iter(self) -> VecMutIterator<'self, T>;
-
- /// Returns a reversed iterator that allows modifying each value
- fn mut_rev_iter(self) -> MutRevIterator<'self, T>;
-
- /**
- * Returns a mutable reference to the first element in this slice
- * and adjusts the slice in place so that it no longer contains
- * that element. O(1).
- *
- * Equivalent to:
- *
- * ```
- * let head = &mut self[0];
- * *self = self.mut_slice_from(1);
- * head
- * ```
- *
- * Fails if slice is empty.
- */
- fn mut_shift_ref(&mut self) -> &'self mut T;
-
- /**
- * Returns a mutable reference to the last element in this slice
- * and adjusts the slice in place so that it no longer contains
- * that element. O(1).
- *
- * Equivalent to:
- *
- * ```
- * let tail = &mut self[self.len() - 1];
- * *self = self.mut_slice_to(self.len() - 1);
- * tail
- * ```
- *
- * Fails if slice is empty.
- */
- fn mut_pop_ref(&mut self) -> &'self mut T;
-
- /**
- * Swaps two elements in a vector
- *
- * # Arguments
- *
- * * a - The index of the first element
- * * b - The index of the second element
- */
- fn swap(self, a: uint, b: uint);
-
- /**
- * Divides one `&mut` into two. The first will
- * contain all indices from `0..mid` (excluding the index `mid`
- * itself) and the second will contain all indices from
- * `mid..len` (excluding the index `len` itself).
- */
- fn mut_split(self, mid: uint) -> (&'self mut [T],
- &'self mut [T]);
-
- /// Reverse the order of elements in a vector, in place
- fn reverse(self);
-
- /**
- * Consumes `src` and moves as many elements as it can into `self`
- * from the range [start,end).
- *
- * Returns the number of elements copied (the shorter of self.len()
- * and end - start).
- *
- * # Arguments
- *
- * * src - A mutable vector of `T`
- * * start - The index into `src` to start copying from
- * * end - The index into `str` to stop copying from
- */
- fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
-
- /// Returns an unsafe mutable pointer to the element in index
- unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T;
- /// Unsafely sets the element in index to the value
- unsafe fn unsafe_set(self, index: uint, val: T);
-
- /// Similar to `as_imm_buf` but passing a `*mut T`
- fn as_mut_buf<U>(self, f: |*mut T, uint| -> U) -> U;
-}
-
-impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
- #[inline]
- fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
- assert!(start <= end);
- assert!(end <= self.len());
- self.as_mut_buf(|p, _len| {
- unsafe {
- cast::transmute(Slice {
- data: ptr::mut_offset(p, start as int) as *T,
- len: (end - start)
- })
- }
- })
- }
-
- #[inline]
- fn mut_slice_from(self, start: uint) -> &'self mut [T] {
- let len = self.len();
- self.mut_slice(start, len)
- }
-
- #[inline]
- fn mut_slice_to(self, end: uint) -> &'self mut [T] {
- self.mut_slice(0, end)
- }
-
- #[inline]
- fn mut_split(self, mid: uint) -> (&'self mut [T], &'self mut [T]) {
- unsafe {
- let len = self.len();
- let self2: &'self mut [T] = cast::transmute_copy(&self);
- (self.mut_slice(0, mid), self2.mut_slice(mid, len))
- }
- }
-
- #[inline]
- fn mut_iter(self) -> VecMutIterator<'self, T> {
- unsafe {
- let p = vec::raw::to_mut_ptr(self);
- if mem::size_of::<T>() == 0 {
- VecMutIterator{ptr: p,
- end: (p as uint + self.len()) as *mut T,
- lifetime: None}
- } else {
- VecMutIterator{ptr: p,
- end: p.offset(self.len() as int),
- lifetime: None}
- }
- }
- }
-
- #[inline]
- fn mut_rev_iter(self) -> MutRevIterator<'self, T> {
- self.mut_iter().invert()
- }
-
- fn mut_shift_ref(&mut self) -> &'self mut T {
- unsafe {
- let s: &mut Slice<T> = cast::transmute(self);
- cast::transmute_mut(&*raw::shift_ptr(s))
- }
- }
-
- fn mut_pop_ref(&mut self) -> &'self mut T {
- unsafe {
- let s: &mut Slice<T> = cast::transmute(self);
- cast::transmute_mut(&*raw::pop_ptr(s))
- }
- }
-
- fn swap(self, a: uint, b: uint) {
- unsafe {
- // Can't take two mutable loans from one vector, so instead just cast
- // them to their raw pointers to do the swap
- let pa: *mut T = &mut self[a];
- let pb: *mut T = &mut self[b];
- ptr::swap_ptr(pa, pb);
- }
- }
-
- fn reverse(self) {
- let mut i: uint = 0;
- let ln = self.len();
- while i < ln / 2 {
- self.swap(i, ln - i - 1);
- i += 1;
- }
- }
-
- #[inline]
- fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
- for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
- util::swap(a, b);
- }
- cmp::min(self.len(), end-start)
- }
-
- #[inline]
- unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T {
- ptr::mut_offset(self.repr().data as *mut T, index as int)
- }
-
- #[inline]
- unsafe fn unsafe_set(self, index: uint, val: T) {
- *self.unsafe_mut_ref(index) = val;
- }
-
- #[inline]
- fn as_mut_buf<U>(self, f: |*mut T, uint| -> U) -> U {
- let Slice{ data, len } = self.repr();
- f(data as *mut T, len)
- }
-}
-
-/// Trait for &[T] where T is Cloneable
-pub trait MutableCloneableVector<T> {
- /// Copies as many elements from `src` as it can into `self`
- /// (the shorter of self.len() and src.len()). Returns the number of elements copied.
- fn copy_from(self, &[T]) -> uint;
-}
-
-impl<'self, T:Clone> MutableCloneableVector<T> for &'self mut [T] {
- #[inline]
- fn copy_from(self, src: &[T]) -> uint {
- for (a, b) in self.mut_iter().zip(src.iter()) {
- a.clone_from(b);
- }
- cmp::min(self.len(), src.len())
- }
-}
-
-/**
-* Constructs a vector from an unsafe pointer to a buffer
-*
-* # Arguments
-*
-* * ptr - An unsafe pointer to a buffer of `T`
-* * elts - The number of elements in the buffer
-*/
-// Wrapper for fn in raw: needs to be called by net_tcp::on_tcp_read_cb
-pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
- raw::from_buf_raw(ptr, elts)
-}
-
-/// Unsafe operations
-pub mod raw {
- use cast;
- use clone::Clone;
- use option::Some;
- use ptr;
- use mem;
- use unstable::intrinsics;
- use vec::{with_capacity, ImmutableVector, MutableVector};
- use unstable::raw::{Box, Vec, Slice};
- use unstable::intrinsics::owns_managed;
-
- /**
- * Sets the length of a vector
- *
- * This will explicitly set the size of the vector, without actually
- * modifying its buffers, so it is up to the caller to ensure that
- * the vector is actually the specified size.
- */
- #[inline]
- pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
- if owns_managed::<T>() {
- let repr: **mut Box<Vec<()>> = cast::transmute(v);
- (**repr).data.fill = new_len * mem::nonzero_size_of::<T>();
- } else {
- let repr: **mut Vec<()> = cast::transmute(v);
- (**repr).fill = new_len * mem::nonzero_size_of::<T>();
- }
- }
-
- /**
- * Returns an unsafe pointer to the vector's buffer
- *
- * The caller must ensure that the vector outlives the pointer this
- * function returns, or else it will end up pointing to garbage.
- *
- * Modifying the vector may cause its buffer to be reallocated, which
- * would also make any pointers to it invalid.
- */
- #[inline]
- pub fn to_ptr<T>(v: &[T]) -> *T {
- v.repr().data
- }
-
- /** see `to_ptr()` */
- #[inline]
- pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
- v.repr().data as *mut T
- }
-
- /**
- * Form a slice from a pointer and length (as a number of units,
- * not bytes).
- */
- #[inline]
- pub unsafe fn buf_as_slice<T,U>(p: *T, len: uint, f: |v: &[T]| -> U)
- -> U {
- f(cast::transmute(Slice {
- data: p,
- len: len
- }))
- }
-
- /**
- * Form a slice from a pointer and length (as a number of units,
- * not bytes).
- */
- #[inline]
- pub unsafe fn mut_buf_as_slice<T,
- U>(
- p: *mut T,
- len: uint,
- f: |v: &mut [T]| -> U)
- -> U {
- f(cast::transmute(Slice {
- data: p as *T,
- len: len
- }))
- }
-
- /**
- * Unchecked vector indexing.
- */
- #[inline]
- pub unsafe fn get<T:Clone>(v: &[T], i: uint) -> T {
- v.as_imm_buf(|p, _len| (*ptr::offset(p, i as int)).clone())
- }
-
- /**
- * Unchecked vector index assignment. Does not drop the
- * old value and hence is only suitable when the vector
- * is newly allocated.
- */
- #[inline]
- pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
- let mut box = Some(val);
- v.as_mut_buf(|p, _len| {
- intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)),
- box.take_unwrap());
- })
- }
-
- /**
- * Constructs a vector from an unsafe pointer to a buffer
- *
- * # Arguments
- *
- * * ptr - An unsafe pointer to a buffer of `T`
- * * elts - The number of elements in the buffer
- */
- // Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
- #[inline]
- pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
- let mut dst = with_capacity(elts);
- set_len(&mut dst, elts);
- dst.as_mut_buf(|p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts));
- dst
- }
-
- /**
- * Copies data from one vector to another.
- *
- * Copies `count` bytes from `src` to `dst`. The source and destination
- * may overlap.
- */
- #[inline]
- pub unsafe fn copy_memory<T>(dst: &mut [T], src: &[T],
- count: uint) {
- assert!(dst.len() >= count);
- assert!(src.len() >= count);
-
- dst.as_mut_buf(|p_dst, _len_dst| {
- src.as_imm_buf(|p_src, _len_src| {
- ptr::copy_memory(p_dst, p_src, count)
- })
- })
- }
-
- /**
- * Returns a pointer to first element in slice and adjusts
- * slice so it no longer contains that element. Fails if
- * slice is empty. O(1).
- */
- pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
- if slice.len == 0 { fail!("shift on empty slice"); }
- let head: *T = slice.data;
- slice.data = ptr::offset(slice.data, 1);
- slice.len -= 1;
- head
- }
-
- /**
- * Returns a pointer to last element in slice and adjusts
- * slice so it no longer contains that element. Fails if
- * slice is empty. O(1).
- */
- pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
- if slice.len == 0 { fail!("pop on empty slice"); }
- let tail: *T = ptr::offset(slice.data, (slice.len - 1) as int);
- slice.len -= 1;
- tail
- }
-}
-
-/// Operations on `[u8]`
-pub mod bytes {
- use libc;
- use num;
- use vec::raw;
- use vec;
- use ptr;
-
- /// A trait for operations on mutable operations on `[u8]`
- pub trait MutableByteVector {
- /// Sets all bytes of the receiver to the given value.
- fn set_memory(self, value: u8);
- }
-
- impl<'self> MutableByteVector for &'self mut [u8] {
- #[inline]
- fn set_memory(self, value: u8) {
- self.as_mut_buf(|p, len| {
- unsafe { ptr::set_memory(p, value, len) };
- })
- }
- }
-
- /// Bytewise string comparison
- pub fn memcmp(a: &~[u8], b: &~[u8]) -> int {
- let a_len = a.len();
- let b_len = b.len();
- let n = num::min(a_len, b_len) as libc::size_t;
- let r = unsafe {
- libc::memcmp(raw::to_ptr(*a) as *libc::c_void,
- raw::to_ptr(*b) as *libc::c_void, n) as int
- };
-
- if r != 0 { r } else {
- if a_len == b_len {
- 0
- } else if a_len < b_len {
- -1
- } else {
- 1
- }
- }
- }
-
- /// Bytewise less than or equal
- pub fn lt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) < 0 }
-
- /// Bytewise less than or equal
- pub fn le(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) <= 0 }
-
- /// Bytewise equality
- pub fn eq(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) == 0 }
-
- /// Bytewise inequality
- pub fn ne(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) != 0 }
-
- /// Bytewise greater than or equal
- pub fn ge(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) >= 0 }
-
- /// Bytewise greater than
- pub fn gt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) > 0 }
-
- /**
- * Copies data from one vector to another.
- *
- * Copies `count` bytes from `src` to `dst`. The source and destination
- * may overlap.
- */
- #[inline]
- pub fn copy_memory(dst: &mut [u8], src: &[u8], count: uint) {
- // Bound checks are done at vec::raw::copy_memory.
- unsafe { vec::raw::copy_memory(dst, src, count) }
- }
-
- /**
- * Allocate space in `dst` and append the data in `src`.
- */
- #[inline]
- pub fn push_bytes(dst: &mut ~[u8], src: &[u8]) {
- let old_len = dst.len();
- dst.reserve_additional(src.len());
- unsafe {
- dst.as_mut_buf(|p_dst, len_dst| {
- src.as_imm_buf(|p_src, len_src| {
- ptr::copy_memory(p_dst.offset(len_dst as int), p_src, len_src)
- })
- });
- vec::raw::set_len(dst, old_len + src.len());
- }
- }
-}
-
-impl<A: Clone> Clone for ~[A] {
- #[inline]
- fn clone(&self) -> ~[A] {
- self.iter().map(|item| item.clone()).collect()
- }
-
- fn clone_from(&mut self, source: &~[A]) {
- if self.len() < source.len() {
- *self = source.clone()
- } else {
- self.truncate(source.len());
- for (x, y) in self.mut_iter().zip(source.iter()) {
- x.clone_from(y);
- }
- }
- }
-}
-
-impl<A: DeepClone> DeepClone for ~[A] {
- #[inline]
- fn deep_clone(&self) -> ~[A] {
- self.iter().map(|item| item.deep_clone()).collect()
- }
-
- fn deep_clone_from(&mut self, source: &~[A]) {
- if self.len() < source.len() {
- *self = source.deep_clone()
- } else {
- self.truncate(source.len());
- for (x, y) in self.mut_iter().zip(source.iter()) {
- x.deep_clone_from(y);
- }
- }
- }
-}
-
-// This works because every lifetime is a sub-lifetime of 'static
-impl<'self, A> Default for &'self [A] {
- fn default() -> &'self [A] { &'self [] }
-}
-
-impl<A> Default for ~[A] {
- fn default() -> ~[A] { ~[] }
-}
-
-impl<A> Default for @[A] {
- fn default() -> @[A] { @[] }
-}
-
-macro_rules! iterator {
- /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
- (struct $name:ident -> $ptr:ty, $elem:ty) => {
- pub struct $name<'self, T> {
- priv ptr: $ptr,
- priv end: $ptr,
- priv lifetime: $elem // FIXME: #5922
- }
- };*/
- (impl $name:ident -> $elem:ty) => {
- impl<'self, T> Iterator<$elem> for $name<'self, T> {
- #[inline]
- fn next(&mut self) -> Option<$elem> {
- // could be implemented with slices, but this avoids bounds checks
- unsafe {
- if self.ptr == self.end {
- None
- } else {
- let old = self.ptr;
- self.ptr = if mem::size_of::<T>() == 0 {
- // purposefully don't use 'ptr.offset' because for
- // vectors with 0-size elements this would return the
- // same pointer.
- cast::transmute(self.ptr as uint + 1)
- } else {
- self.ptr.offset(1)
- };
-
- Some(cast::transmute(old))
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let diff = (self.end as uint) - (self.ptr as uint);
- let exact = diff / mem::nonzero_size_of::<T>();
- (exact, Some(exact))
- }
- }
- }
-}
-
-macro_rules! double_ended_iterator {
- (impl $name:ident -> $elem:ty) => {
- impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
- #[inline]
- fn next_back(&mut self) -> Option<$elem> {
- // could be implemented with slices, but this avoids bounds checks
- unsafe {
- if self.end == self.ptr {
- None
- } else {
- self.end = if mem::size_of::<T>() == 0 {
- // See above for why 'ptr.offset' isn't used
- cast::transmute(self.end as uint - 1)
- } else {
- self.end.offset(-1)
- };
- Some(cast::transmute(self.end))
- }
- }
- }
- }
- }
-}
-
-impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> {
- #[inline]
- fn indexable(&self) -> uint {
- let (exact, _) = self.size_hint();
- exact
- }
-
- #[inline]
- fn idx(&self, index: uint) -> Option<&'self T> {
- unsafe {
- if index < self.indexable() {
- cast::transmute(self.ptr.offset(index as int))
- } else {
- None
- }
- }
- }
-}
-
-//iterator!{struct VecIterator -> *T, &'self T}
-/// An iterator for iterating over a vector.
-pub struct VecIterator<'self, T> {
- priv ptr: *T,
- priv end: *T,
- priv lifetime: Option<&'self ()> // FIXME: #5922
-}
-iterator!{impl VecIterator -> &'self T}
-double_ended_iterator!{impl VecIterator -> &'self T}
-pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
-
-impl<'self, T> ExactSize<&'self T> for VecIterator<'self, T> {}
-impl<'self, T> ExactSize<&'self mut T> for VecMutIterator<'self, T> {}
-
-impl<'self, T> Clone for VecIterator<'self, T> {
- fn clone(&self) -> VecIterator<'self, T> { *self }
-}
-
-//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
-/// An iterator for mutating the elements of a vector.
-pub struct VecMutIterator<'self, T> {
- priv ptr: *mut T,
- priv end: *mut T,
- priv lifetime: Option<&'self mut ()> // FIXME: #5922
-}
-iterator!{impl VecMutIterator -> &'self mut T}
-double_ended_iterator!{impl VecMutIterator -> &'self mut T}
-pub type MutRevIterator<'self, T> = Invert<VecMutIterator<'self, T>>;
-
-/// An iterator that moves out of a vector.
-#[deriving(Clone)]
-pub struct MoveIterator<T> {
- priv v: ~[T],
- priv idx: uint,
-}
-
-impl<T> Iterator<T> for MoveIterator<T> {
- #[inline]
- fn next(&mut self) -> Option<T> {
- // this is peculiar, but is required for safety with respect
- // to dtors. It traverses the first half of the vec, and
- // removes them by swapping them with the last element (and
- // popping), which results in the second half in reverse
- // order, and so these can just be pop'd off. That is,
- //
- // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4,
- // [5] -> 5, []
- let l = self.v.len();
- if self.idx < l {
- self.v.swap(self.idx, l - 1);
- self.idx += 1;
- }
-
- self.v.pop_opt()
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let l = self.v.len();
- (l, Some(l))
- }
-}
-
-/// An iterator that moves out of a vector in reverse order.
-#[deriving(Clone)]
-pub struct MoveRevIterator<T> {
- priv v: ~[T]
-}
-
-impl<T> Iterator<T> for MoveRevIterator<T> {
- #[inline]
- fn next(&mut self) -> Option<T> {
- self.v.pop_opt()
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let l = self.v.len();
- (l, Some(l))
- }
-}
-
-impl<A> FromIterator<A> for ~[A] {
- fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
- let (lower, _) = iterator.size_hint();
- let mut xs = with_capacity(lower);
- for x in *iterator {
- xs.push(x);
- }
- xs
- }
-}
-
-impl<A> Extendable<A> for ~[A] {
- fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
- let (lower, _) = iterator.size_hint();
- let len = self.len();
- self.reserve(len + lower);
- for x in *iterator {
- self.push(x);
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use option::{None, Option, Some};
- use mem;
- use vec::*;
- use cmp::*;
- use prelude::*;
-
- fn square(n: uint) -> uint { n * n }
-
- fn square_ref(n: &uint) -> uint { square(*n) }
-
- fn is_three(n: &uint) -> bool { *n == 3u }
-
- fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
-
- fn is_equal(x: &uint, y:&uint) -> bool { *x == *y }
-
- fn square_if_odd_r(n: &uint) -> Option<uint> {
- if *n % 2u == 1u { Some(*n * *n) } else { None }
- }
-
- fn square_if_odd_v(n: uint) -> Option<uint> {
- if n % 2u == 1u { Some(n * n) } else { None }
- }
-
- fn add(x: uint, y: &uint) -> uint { x + *y }
-
- #[test]
- fn test_unsafe_ptrs() {
- unsafe {
- // Test on-stack copy-from-buf.
- let a = ~[1, 2, 3];
- let mut ptr = raw::to_ptr(a);
- let b = from_buf(ptr, 3u);
- assert_eq!(b.len(), 3u);
- assert_eq!(b[0], 1);
- assert_eq!(b[1], 2);
- assert_eq!(b[2], 3);
-
- // Test on-heap copy-from-buf.
- let c = ~[1, 2, 3, 4, 5];
- ptr = raw::to_ptr(c);
- let d = from_buf(ptr, 5u);
- assert_eq!(d.len(), 5u);
- assert_eq!(d[0], 1);
- assert_eq!(d[1], 2);
- assert_eq!(d[2], 3);
- assert_eq!(d[3], 4);
- assert_eq!(d[4], 5);
- }
- }
-
- #[test]
- fn test_from_fn() {
- // Test on-stack from_fn.
- let mut v = from_fn(3u, square);
- assert_eq!(v.len(), 3u);
- assert_eq!(v[0], 0u);
- assert_eq!(v[1], 1u);
- assert_eq!(v[2], 4u);
-
- // Test on-heap from_fn.
- v = from_fn(5u, square);
- assert_eq!(v.len(), 5u);
- assert_eq!(v[0], 0u);
- assert_eq!(v[1], 1u);
- assert_eq!(v[2], 4u);
- assert_eq!(v[3], 9u);
- assert_eq!(v[4], 16u);
- }
-
- #[test]
- fn test_from_elem() {
- // Test on-stack from_elem.
- let mut v = from_elem(2u, 10u);
- assert_eq!(v.len(), 2u);
- assert_eq!(v[0], 10u);
- assert_eq!(v[1], 10u);
-
- // Test on-heap from_elem.
- v = from_elem(6u, 20u);
- assert_eq!(v[0], 20u);
- assert_eq!(v[1], 20u);
- assert_eq!(v[2], 20u);
- assert_eq!(v[3], 20u);
- assert_eq!(v[4], 20u);
- assert_eq!(v[5], 20u);
- }
-
- #[test]
- fn test_is_empty() {
- let xs: [int, ..0] = [];
- assert!(xs.is_empty());
- assert!(![0].is_empty());
- }
-
- #[test]
- fn test_len_divzero() {
- type Z = [i8, ..0];
- let v0 : &[Z] = &[];
- let v1 : &[Z] = &[[]];
- let v2 : &[Z] = &[[], []];
- assert_eq!(mem::size_of::<Z>(), 0);
- assert_eq!(v0.len(), 0);
- assert_eq!(v1.len(), 1);
- assert_eq!(v2.len(), 2);
- }
-
- #[test]
- fn test_get_opt() {
- let mut a = ~[11];
- assert_eq!(a.get_opt(1), None);
- a = ~[11, 12];
- assert_eq!(a.get_opt(1).unwrap(), &12);
- a = ~[11, 12, 13];
- assert_eq!(a.get_opt(1).unwrap(), &12);
- }
-
- #[test]
- fn test_head() {
- let mut a = ~[11];
- assert_eq!(a.head(), &11);
- a = ~[11, 12];
- assert_eq!(a.head(), &11);
- }
-
- #[test]
- #[should_fail]
- fn test_head_empty() {
- let a: ~[int] = ~[];
- a.head();
- }
-
- #[test]
- fn test_head_opt() {
- let mut a = ~[];
- assert_eq!(a.head_opt(), None);
- a = ~[11];
- assert_eq!(a.head_opt().unwrap(), &11);
- a = ~[11, 12];
- assert_eq!(a.head_opt().unwrap(), &11);
- }
-
- #[test]
- fn test_tail() {
- let mut a = ~[11];
- assert_eq!(a.tail(), &[]);
- a = ~[11, 12];
- assert_eq!(a.tail(), &[12]);
- }
-
- #[test]
- #[should_fail]
- fn test_tail_empty() {
- let a: ~[int] = ~[];
- a.tail();
- }
-
- #[test]
- fn test_tailn() {
- let mut a = ~[11, 12, 13];
- assert_eq!(a.tailn(0), &[11, 12, 13]);
- a = ~[11, 12, 13];
- assert_eq!(a.tailn(2), &[13]);
- }
-
- #[test]
- #[should_fail]
- fn test_tailn_empty() {
- let a: ~[int] = ~[];
- a.tailn(2);
- }
-
- #[test]
- fn test_init() {
- let mut a = ~[11];
- assert_eq!(a.init(), &[]);
- a = ~[11, 12];
- assert_eq!(a.init(), &[11]);
- }
-
- #[test]
- #[should_fail]
- fn test_init_empty() {
- let a: ~[int] = ~[];
- a.init();
- }
-
- #[test]
- fn test_initn() {
- let mut a = ~[11, 12, 13];
- assert_eq!(a.initn(0), &[11, 12, 13]);
- a = ~[11, 12, 13];
- assert_eq!(a.initn(2), &[11]);
- }
-
- #[test]
- #[should_fail]
- fn test_initn_empty() {
- let a: ~[int] = ~[];
- a.initn(2);
- }
-
- #[test]
- fn test_last() {
- let mut a = ~[11];
- assert_eq!(a.last(), &11);
- a = ~[11, 12];
- assert_eq!(a.last(), &12);
- }
-
- #[test]
- #[should_fail]
- fn test_last_empty() {
- let a: ~[int] = ~[];
- a.last();
- }
-
- #[test]
- fn test_last_opt() {
- let mut a = ~[];
- assert_eq!(a.last_opt(), None);
- a = ~[11];
- assert_eq!(a.last_opt().unwrap(), &11);
- a = ~[11, 12];
- assert_eq!(a.last_opt().unwrap(), &12);
- }
-
- #[test]
- fn test_slice() {
- // Test fixed length vector.
- let vec_fixed = [1, 2, 3, 4];
- let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
- assert_eq!(v_a.len(), 3u);
- assert_eq!(v_a[0], 2);
- assert_eq!(v_a[1], 3);
- assert_eq!(v_a[2], 4);
-
- // Test on stack.
- let vec_stack = &[1, 2, 3];
- let v_b = vec_stack.slice(1u, 3u).to_owned();
- assert_eq!(v_b.len(), 2u);
- assert_eq!(v_b[0], 2);
- assert_eq!(v_b[1], 3);
-
- // Test on managed heap.
- let vec_managed = @[1, 2, 3, 4, 5];
- let v_c = vec_managed.slice(0u, 3u).to_owned();
- assert_eq!(v_c.len(), 3u);
- assert_eq!(v_c[0], 1);
- assert_eq!(v_c[1], 2);
- assert_eq!(v_c[2], 3);
-
- // Test on exchange heap.
- let vec_unique = ~[1, 2, 3, 4, 5, 6];
- let v_d = vec_unique.slice(1u, 6u).to_owned();
- assert_eq!(v_d.len(), 5u);
- assert_eq!(v_d[0], 2);
- assert_eq!(v_d[1], 3);
- assert_eq!(v_d[2], 4);
- assert_eq!(v_d[3], 5);
- assert_eq!(v_d[4], 6);
- }
-
- #[test]
- fn test_slice_from() {
- let vec = &[1, 2, 3, 4];
- assert_eq!(vec.slice_from(0), vec);
- assert_eq!(vec.slice_from(2), &[3, 4]);
- assert_eq!(vec.slice_from(4), &[]);
- }
-
- #[test]
- fn test_slice_to() {
- let vec = &[1, 2, 3, 4];
- assert_eq!(vec.slice_to(4), vec);
- assert_eq!(vec.slice_to(2), &[1, 2]);
- assert_eq!(vec.slice_to(0), &[]);
- }
-
- #[test]
- fn test_pop() {
- // Test on-heap pop.
- let mut v = ~[1, 2, 3, 4, 5];
- let e = v.pop();
- assert_eq!(v.len(), 4u);
- assert_eq!(v[0], 1);
- assert_eq!(v[1], 2);
- assert_eq!(v[2], 3);
- assert_eq!(v[3], 4);
- assert_eq!(e, 5);
- }
-
- #[test]
- fn test_pop_opt() {
- let mut v = ~[5];
- let e = v.pop_opt();
- assert_eq!(v.len(), 0);
- assert_eq!(e, Some(5));
- let f = v.pop_opt();
- assert_eq!(f, None);
- let g = v.pop_opt();
- assert_eq!(g, None);
- }
-
- fn test_swap_remove() {
- let mut v = ~[1, 2, 3, 4, 5];
- let mut e = v.swap_remove(0);
- assert_eq!(v.len(), 4);
- assert_eq!(e, 1);
- assert_eq!(v[0], 5);
- e = v.swap_remove(3);
- assert_eq!(v.len(), 3);
- assert_eq!(e, 4);
- assert_eq!(v[0], 5);
- assert_eq!(v[1], 2);
- assert_eq!(v[2], 3);
- }
-
- #[test]
- fn test_swap_remove_noncopyable() {
- // Tests that we don't accidentally run destructors twice.
- let mut v = ~[::unstable::sync::Exclusive::new(()),
- ::unstable::sync::Exclusive::new(()),
- ::unstable::sync::Exclusive::new(())];
- let mut _e = v.swap_remove(0);
- assert_eq!(v.len(), 2);
- _e = v.swap_remove(1);
- assert_eq!(v.len(), 1);
- _e = v.swap_remove(0);
- assert_eq!(v.len(), 0);
- }
-
- #[test]
- fn test_push() {
- // Test on-stack push().
- let mut v = ~[];
- v.push(1);
- assert_eq!(v.len(), 1u);
- assert_eq!(v[0], 1);
-
- // Test on-heap push().
- v.push(2);
- assert_eq!(v.len(), 2u);
- assert_eq!(v[0], 1);
- assert_eq!(v[1], 2);
- }
-
- #[test]
- fn test_grow() {
- // Test on-stack grow().
- let mut v = ~[];
- v.grow(2u, &1);
- assert_eq!(v.len(), 2u);
- assert_eq!(v[0], 1);
- assert_eq!(v[1], 1);
-
- // Test on-heap grow().
- v.grow(3u, &2);
- assert_eq!(v.len(), 5u);
- assert_eq!(v[0], 1);
- assert_eq!(v[1], 1);
- assert_eq!(v[2], 2);
- assert_eq!(v[3], 2);
- assert_eq!(v[4], 2);
- }
-
- #[test]
- fn test_grow_fn() {
- let mut v = ~[];
- v.grow_fn(3u, square);
- assert_eq!(v.len(), 3u);
- assert_eq!(v[0], 0u);
- assert_eq!(v[1], 1u);
- assert_eq!(v[2], 4u);
- }
-
- #[test]
- fn test_grow_set() {
- let mut v = ~[1, 2, 3];
- v.grow_set(4u, &4, 5);
- assert_eq!(v.len(), 5u);
- assert_eq!(v[0], 1);
- assert_eq!(v[1], 2);
- assert_eq!(v[2], 3);
- assert_eq!(v[3], 4);
- assert_eq!(v[4], 5);
- }
-
- #[test]
- fn test_truncate() {
- let mut v = ~[@6,@5,@4];
- v.truncate(1);
- assert_eq!(v.len(), 1);
- assert_eq!(*(v[0]), 6);
- // If the unsafe block didn't drop things properly, we blow up here.
- }
-
- #[test]
- fn test_clear() {
- let mut v = ~[@6,@5,@4];
- v.clear();
- assert_eq!(v.len(), 0);
- // If the unsafe block didn't drop things properly, we blow up here.
- }
-
- #[test]
- fn test_dedup() {
- fn case(a: ~[uint], b: ~[uint]) {
- let mut v = a;
- v.dedup();
- assert_eq!(v, b);
- }
- case(~[], ~[]);
- case(~[1], ~[1]);
- case(~[1,1], ~[1]);
- case(~[1,2,3], ~[1,2,3]);
- case(~[1,1,2,3], ~[1,2,3]);
- case(~[1,2,2,3], ~[1,2,3]);
- case(~[1,2,3,3], ~[1,2,3]);
- case(~[1,1,2,2,2,3,3], ~[1,2,3]);
- }
-
- #[test]
- fn test_dedup_unique() {
- let mut v0 = ~[~1, ~1, ~2, ~3];
- v0.dedup();
- let mut v1 = ~[~1, ~2, ~2, ~3];
- v1.dedup();
- let mut v2 = ~[~1, ~2, ~3, ~3];
- v2.dedup();
- /*
- * If the ~pointers were leaked or otherwise misused, valgrind and/or
- * rustrt should raise errors.
- */
- }
-
- #[test]
- fn test_dedup_shared() {
- let mut v0 = ~[@1, @1, @2, @3];
- v0.dedup();
- let mut v1 = ~[@1, @2, @2, @3];
- v1.dedup();
- let mut v2 = ~[@1, @2, @3, @3];
- v2.dedup();
- /*
- * If the @pointers were leaked or otherwise misused, valgrind and/or
- * rustrt should raise errors.
- */
- }
-
- #[test]
- fn test_map() {
- // Test on-stack map.
- let v = &[1u, 2u, 3u];
- let mut w = v.map(square_ref);
- assert_eq!(w.len(), 3u);
- assert_eq!(w[0], 1u);
- assert_eq!(w[1], 4u);
- assert_eq!(w[2], 9u);
-
- // Test on-heap map.
- let v = ~[1u, 2u, 3u, 4u, 5u];
- w = v.map(square_ref);
- assert_eq!(w.len(), 5u);
- assert_eq!(w[0], 1u);
- assert_eq!(w[1], 4u);
- assert_eq!(w[2], 9u);
- assert_eq!(w[3], 16u);
- assert_eq!(w[4], 25u);
- }
-
- #[test]
- fn test_retain() {
- let mut v = ~[1, 2, 3, 4, 5];
- v.retain(is_odd);
- assert_eq!(v, ~[1, 3, 5]);
- }
-
- #[test]
- fn test_zip_unzip() {
- let z1 = ~[(1, 4), (2, 5), (3, 6)];
-
- let (left, right) = unzip(z1.iter().map(|&x| x));
-
- assert_eq!((1, 4), (left[0], right[0]));
- assert_eq!((2, 5), (left[1], right[1]));
- assert_eq!((3, 6), (left[2], right[2]));
- }
-
- #[test]
- fn test_element_swaps() {
- let mut v = [1, 2, 3];
- for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
- v.swap(a, b);
- match i {
- 0 => assert_eq!(v, [1, 3, 2]),
- 1 => assert_eq!(v, [3, 1, 2]),
- 2 => assert_eq!(v, [3, 2, 1]),
- 3 => assert_eq!(v, [2, 3, 1]),
- 4 => assert_eq!(v, [2, 1, 3]),
- 5 => assert_eq!(v, [1, 2, 3]),
- _ => fail!(),
- }
- }
- }
-
- #[test]
- fn test_permutations() {
- use hashmap;
- {
- let v: [int, ..0] = [];
- let mut it = v.permutations();
- assert_eq!(it.next(), None);
- }
- {
- let v = [~"Hello"];
- let mut it = v.permutations();
- assert_eq!(it.next(), None);
- }
- {
- let v = [1, 2, 3];
- let mut it = v.permutations();
- assert_eq!(it.next(), Some(~[1,2,3]));
- assert_eq!(it.next(), Some(~[1,3,2]));
- assert_eq!(it.next(), Some(~[3,1,2]));
- assert_eq!(it.next(), Some(~[3,2,1]));
- assert_eq!(it.next(), Some(~[2,3,1]));
- assert_eq!(it.next(), Some(~[2,1,3]));
- assert_eq!(it.next(), None);
- }
- {
- // check that we have N! unique permutations
- let mut set = hashmap::HashSet::new();
- let v = ['A', 'B', 'C', 'D', 'E', 'F'];
- for perm in v.permutations() {
- set.insert(perm);
- }
- assert_eq!(set.len(), 2 * 3 * 4 * 5 * 6);
- }
- }
-
- #[test]
- fn test_position_elem() {
- assert!([].position_elem(&1).is_none());
-
- let v1 = ~[1, 2, 3, 3, 2, 5];
- assert_eq!(v1.position_elem(&1), Some(0u));
- assert_eq!(v1.position_elem(&2), Some(1u));
- assert_eq!(v1.position_elem(&5), Some(5u));
- assert!(v1.position_elem(&4).is_none());
- }
-
- #[test]
- fn test_bsearch_elem() {
- assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4));
- assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3));
- assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2));
- assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1));
- assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0));
-
- assert_eq!([2,4,6,8,10].bsearch_elem(&1), None);
- assert_eq!([2,4,6,8,10].bsearch_elem(&5), None);
- assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1));
- assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4));
-
- assert_eq!([2,4,6,8].bsearch_elem(&1), None);
- assert_eq!([2,4,6,8].bsearch_elem(&5), None);
- assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1));
- assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3));
-
- assert_eq!([2,4,6].bsearch_elem(&1), None);
- assert_eq!([2,4,6].bsearch_elem(&5), None);
- assert_eq!([2,4,6].bsearch_elem(&4), Some(1));
- assert_eq!([2,4,6].bsearch_elem(&6), Some(2));
-
- assert_eq!([2,4].bsearch_elem(&1), None);
- assert_eq!([2,4].bsearch_elem(&5), None);
- assert_eq!([2,4].bsearch_elem(&2), Some(0));
- assert_eq!([2,4].bsearch_elem(&4), Some(1));
-
- assert_eq!([2].bsearch_elem(&1), None);
- assert_eq!([2].bsearch_elem(&5), None);
- assert_eq!([2].bsearch_elem(&2), Some(0));
-
- assert_eq!([].bsearch_elem(&1), None);
- assert_eq!([].bsearch_elem(&5), None);
-
- assert!([1,1,1,1,1].bsearch_elem(&1) != None);
- assert!([1,1,1,1,2].bsearch_elem(&1) != None);
- assert!([1,1,1,2,2].bsearch_elem(&1) != None);
- assert!([1,1,2,2,2].bsearch_elem(&1) != None);
- assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0));
-
- assert_eq!([1,2,3,4,5].bsearch_elem(&6), None);
- assert_eq!([1,2,3,4,5].bsearch_elem(&0), None);
- }
-
- #[test]
- fn test_reverse() {
- let mut v: ~[int] = ~[10, 20];
- assert_eq!(v[0], 10);
- assert_eq!(v[1], 20);
- v.reverse();
- assert_eq!(v[0], 20);
- assert_eq!(v[1], 10);
-
- let mut v3: ~[int] = ~[];
- v3.reverse();
- assert!(v3.is_empty());
- }
-
- #[test]
- fn test_partition() {
- assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[]));
- assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
- assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 2), (~[1], ~[2, 3]));
- assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
- }
-
- #[test]
- fn test_partitioned() {
- assert_eq!(([]).partitioned(|x: &int| *x < 3), (~[], ~[]))
- assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
- assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (~[1], ~[2, 3]));
- assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
- }
-
- #[test]
- fn test_concat() {
- let v: [~[int], ..0] = [];
- assert_eq!(v.concat_vec(), ~[]);
- assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
-
- assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
- }
-
- #[test]
- fn test_connect() {
- let v: [~[int], ..0] = [];
- assert_eq!(v.connect_vec(&0), ~[]);
- assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
- assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
-
- assert_eq!(v.connect_vec(&0), ~[]);
- assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
- assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
- }
-
- #[test]
- fn test_shift() {
- let mut x = ~[1, 2, 3];
- assert_eq!(x.shift(), 1);
- assert_eq!(&x, &~[2, 3]);
- assert_eq!(x.shift(), 2);
- assert_eq!(x.shift(), 3);
- assert_eq!(x.len(), 0);
- }
-
- #[test]
- fn test_shift_opt() {
- let mut x = ~[1, 2, 3];
- assert_eq!(x.shift_opt(), Some(1));
- assert_eq!(&x, &~[2, 3]);
- assert_eq!(x.shift_opt(), Some(2));
- assert_eq!(x.shift_opt(), Some(3));
- assert_eq!(x.shift_opt(), None);
- assert_eq!(x.len(), 0);
- }
-
- #[test]
- fn test_unshift() {
- let mut x = ~[1, 2, 3];
- x.unshift(0);
- assert_eq!(x, ~[0, 1, 2, 3]);
- }
-
- #[test]
- fn test_insert() {
- let mut a = ~[1, 2, 4];
- a.insert(2, 3);
- assert_eq!(a, ~[1, 2, 3, 4]);
-
- let mut a = ~[1, 2, 3];
- a.insert(0, 0);
- assert_eq!(a, ~[0, 1, 2, 3]);
-
- let mut a = ~[1, 2, 3];
- a.insert(3, 4);
- assert_eq!(a, ~[1, 2, 3, 4]);
-
- let mut a = ~[];
- a.insert(0, 1);
- assert_eq!(a, ~[1]);
- }
-
- #[test]
- #[should_fail]
- fn test_insert_oob() {
- let mut a = ~[1, 2, 3];
- a.insert(4, 5);
- }
-
- #[test]
- fn test_remove() {
- let mut a = ~[1, 2, 3, 4];
- a.remove(2);
- assert_eq!(a, ~[1, 2, 4]);
-
- let mut a = ~[1, 2, 3];
- a.remove(0);
- assert_eq!(a, ~[2, 3]);
-
- let mut a = ~[1];
- a.remove(0);
- assert_eq!(a, ~[]);
- }
-
- #[test]
- #[should_fail]
- fn test_remove_oob() {
- let mut a = ~[1, 2, 3];
- a.remove(3);
- }
-
- #[test]
- fn test_capacity() {
- let mut v = ~[0u64];
- v.reserve(10u);
- assert_eq!(v.capacity(), 10u);
- let mut v = ~[0u32];
- v.reserve(10u);
- assert_eq!(v.capacity(), 10u);
- }
-
- #[test]
- fn test_slice_2() {
- let v = ~[1, 2, 3, 4, 5];
- let v = v.slice(1u, 3u);
- assert_eq!(v.len(), 2u);
- assert_eq!(v[0], 2);
- assert_eq!(v[1], 3);
- }
-
-
- #[test]
- #[should_fail]
- fn test_from_fn_fail() {
- from_fn(100, |v| {
- if v == 50 { fail!() }
- (~0, @0)
- });
- }
-
- #[test]
- #[should_fail]
- fn test_from_elem_fail() {
- use cast;
-
- struct S {
- f: int,
- boxes: (~int, @int)
- }
-
- impl Clone for S {
- fn clone(&self) -> S {
- let s = unsafe { cast::transmute_mut(self) };
- s.f += 1;
- if s.f == 10 { fail!() }
- S { f: s.f, boxes: s.boxes.clone() }
- }
- }
-
- let s = S { f: 0, boxes: (~0, @0) };
- let _ = from_elem(100, s);
- }
-
- #[test]
- #[should_fail]
- fn test_build_fail() {
- build(None, |push| {
- push((~0, @0));
- push((~0, @0));
- push((~0, @0));
- push((~0, @0));
- fail!();
- });
- }
-
- #[test]
- #[should_fail]
- fn test_grow_fn_fail() {
- let mut v = ~[];
- v.grow_fn(100, |i| {
- if i == 50 {
- fail!()
- }
- (~0, @0)
- })
- }
-
- #[test]
- #[should_fail]
- fn test_map_fail() {
- let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
- let mut i = 0;
- v.map(|_elt| {
- if i == 2 {
- fail!()
- }
- i += 1;
- ~[(~0, @0)]
- });
- }
-
- #[test]
- #[should_fail]
- fn test_flat_map_fail() {
- let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
- let mut i = 0;
- flat_map(v, |_elt| {
- if i == 2 {
- fail!()
- }
- i += 1;
- ~[(~0, @0)]
- });
- }
-
- #[test]
- #[should_fail]
- fn test_permute_fail() {
- let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
- let mut i = 0;
- for _ in v.permutations() {
- if i == 2 {
- fail!()
- }
- i += 1;
- }
- }
-
- #[test]
- #[should_fail]
- fn test_as_imm_buf_fail() {
- let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
- v.as_imm_buf(|_buf, _i| {
- fail!()
- })
- }
-
- #[test]
- #[should_fail]
- fn test_as_mut_buf_fail() {
- let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
- v.as_mut_buf(|_buf, _i| {
- fail!()
- })
- }
-
- #[test]
- #[should_fail]
- fn test_copy_memory_oob() {
- unsafe {
- let mut a = [1, 2, 3, 4];
- let b = [1, 2, 3, 4, 5];
- raw::copy_memory(a, b, 5);
- }
- }
-
- #[test]
- fn test_total_ord() {
- [1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
- [1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
- [1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
- [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
- [2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
- }
-
- #[test]
- fn test_iterator() {
- use iter::*;
- let xs = [1, 2, 5, 10, 11];
- let mut it = xs.iter();
- assert_eq!(it.size_hint(), (5, Some(5)));
- assert_eq!(it.next().unwrap(), &1);
- assert_eq!(it.size_hint(), (4, Some(4)));
- assert_eq!(it.next().unwrap(), &2);
- assert_eq!(it.size_hint(), (3, Some(3)));
- assert_eq!(it.next().unwrap(), &5);
- assert_eq!(it.size_hint(), (2, Some(2)));
- assert_eq!(it.next().unwrap(), &10);
- assert_eq!(it.size_hint(), (1, Some(1)));
- assert_eq!(it.next().unwrap(), &11);
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_random_access_iterator() {
- use iter::*;
- let xs = [1, 2, 5, 10, 11];
- let mut it = xs.iter();
-
- assert_eq!(it.indexable(), 5);
- assert_eq!(it.idx(0).unwrap(), &1);
- assert_eq!(it.idx(2).unwrap(), &5);
- assert_eq!(it.idx(4).unwrap(), &11);
- assert!(it.idx(5).is_none());
-
- assert_eq!(it.next().unwrap(), &1);
- assert_eq!(it.indexable(), 4);
- assert_eq!(it.idx(0).unwrap(), &2);
- assert_eq!(it.idx(3).unwrap(), &11);
- assert!(it.idx(4).is_none());
-
- assert_eq!(it.next().unwrap(), &2);
- assert_eq!(it.indexable(), 3);
- assert_eq!(it.idx(1).unwrap(), &10);
- assert!(it.idx(3).is_none());
-
- assert_eq!(it.next().unwrap(), &5);
- assert_eq!(it.indexable(), 2);
- assert_eq!(it.idx(1).unwrap(), &11);
-
- assert_eq!(it.next().unwrap(), &10);
- assert_eq!(it.indexable(), 1);
- assert_eq!(it.idx(0).unwrap(), &11);
- assert!(it.idx(1).is_none());
-
- assert_eq!(it.next().unwrap(), &11);
- assert_eq!(it.indexable(), 0);
- assert!(it.idx(0).is_none());
-
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_iter_size_hints() {
- use iter::*;
- let mut xs = [1, 2, 5, 10, 11];
- assert_eq!(xs.iter().size_hint(), (5, Some(5)));
- assert_eq!(xs.rev_iter().size_hint(), (5, Some(5)));
- assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
- assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5)));
- }
-
- #[test]
- fn test_iter_clone() {
- let xs = [1, 2, 5];
- let mut it = xs.iter();
- it.next();
- let mut jt = it.clone();
- assert_eq!(it.next(), jt.next());
- assert_eq!(it.next(), jt.next());
- assert_eq!(it.next(), jt.next());
- }
-
- #[test]
- fn test_mut_iterator() {
- use iter::*;
- let mut xs = [1, 2, 3, 4, 5];
- for x in xs.mut_iter() {
- *x += 1;
- }
- assert_eq!(xs, [2, 3, 4, 5, 6])
- }
-
- #[test]
- fn test_rev_iterator() {
- use iter::*;
-
- let xs = [1, 2, 5, 10, 11];
- let ys = [11, 10, 5, 2, 1];
- let mut i = 0;
- for &x in xs.rev_iter() {
- assert_eq!(x, ys[i]);
- i += 1;
- }
- assert_eq!(i, 5);
- }
-
- #[test]
- fn test_mut_rev_iterator() {
- use iter::*;
- let mut xs = [1u, 2, 3, 4, 5];
- for (i,x) in xs.mut_rev_iter().enumerate() {
- *x += i;
- }
- assert_eq!(xs, [5, 5, 5, 5, 5])
- }
-
- #[test]
- fn test_move_iterator() {
- use iter::*;
- let xs = ~[1u,2,3,4,5];
- assert_eq!(xs.move_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
- }
-
- #[test]
- fn test_move_rev_iterator() {
- use iter::*;
- let xs = ~[1u,2,3,4,5];
- assert_eq!(xs.move_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321);
- }
-
- #[test]
- fn test_splitator() {
- let xs = &[1i,2,3,4,5];
-
- assert_eq!(xs.split(|x| *x % 2 == 0).collect::<~[&[int]]>(),
- ~[&[1], &[3], &[5]]);
- assert_eq!(xs.split(|x| *x == 1).collect::<~[&[int]]>(),
- ~[&[], &[2,3,4,5]]);
- assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(),
- ~[&[1,2,3,4], &[]]);
- assert_eq!(xs.split(|x| *x == 10).collect::<~[&[int]]>(),
- ~[&[1,2,3,4,5]]);
- assert_eq!(xs.split(|_| true).collect::<~[&[int]]>(),
- ~[&[], &[], &[], &[], &[], &[]]);
-
- let xs: &[int] = &[];
- assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
- }
-
- #[test]
- fn test_splitnator() {
- let xs = &[1i,2,3,4,5];
-
- assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
- ~[&[1,2,3,4,5]]);
- assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
- ~[&[1], &[3,4,5]]);
- assert_eq!(xs.splitn(3, |_| true).collect::<~[&[int]]>(),
- ~[&[], &[], &[], &[4,5]]);
-
- let xs: &[int] = &[];
- assert_eq!(xs.splitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
- }
-
- #[test]
- fn test_rsplitator() {
- let xs = &[1i,2,3,4,5];
-
- assert_eq!(xs.rsplit(|x| *x % 2 == 0).collect::<~[&[int]]>(),
- ~[&[5], &[3], &[1]]);
- assert_eq!(xs.rsplit(|x| *x == 1).collect::<~[&[int]]>(),
- ~[&[2,3,4,5], &[]]);
- assert_eq!(xs.rsplit(|x| *x == 5).collect::<~[&[int]]>(),
- ~[&[], &[1,2,3,4]]);
- assert_eq!(xs.rsplit(|x| *x == 10).collect::<~[&[int]]>(),
- ~[&[1,2,3,4,5]]);
-
- let xs: &[int] = &[];
- assert_eq!(xs.rsplit(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
- }
-
- #[test]
- fn test_rsplitnator() {
- let xs = &[1,2,3,4,5];
-
- assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
- ~[&[1,2,3,4,5]]);
- assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
- ~[&[5], &[1,2,3]]);
- assert_eq!(xs.rsplitn(3, |_| true).collect::<~[&[int]]>(),
- ~[&[], &[], &[], &[1,2]]);
-
- let xs: &[int] = &[];
- assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
- }
-
- #[test]
- fn test_windowsator() {
- let v = &[1i,2,3,4];
-
- assert_eq!(v.windows(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]);
- assert_eq!(v.windows(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]);
- assert!(v.windows(6).next().is_none());
- }
-
- #[test]
- #[should_fail]
- fn test_windowsator_0() {
- let v = &[1i,2,3,4];
- let _it = v.windows(0);
- }
-
- #[test]
- fn test_chunksator() {
- let v = &[1i,2,3,4,5];
-
- assert_eq!(v.chunks(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
- assert_eq!(v.chunks(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
- assert_eq!(v.chunks(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
-
- assert_eq!(v.chunks(2).invert().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
- let it = v.chunks(2);
- assert_eq!(it.indexable(), 3);
- assert_eq!(it.idx(0).unwrap(), &[1,2]);
- assert_eq!(it.idx(1).unwrap(), &[3,4]);
- assert_eq!(it.idx(2).unwrap(), &[5]);
- assert_eq!(it.idx(3), None);
- }
-
- #[test]
- #[should_fail]
- fn test_chunksator_0() {
- let v = &[1i,2,3,4];
- let _it = v.chunks(0);
- }
-
- #[test]
- fn test_move_from() {
- let mut a = [1,2,3,4,5];
- let b = ~[6,7,8];
- assert_eq!(a.move_from(b, 0, 3), 3);
- assert_eq!(a, [6,7,8,4,5]);
- let mut a = [7,2,8,1];
- let b = ~[3,1,4,1,5,9];
- assert_eq!(a.move_from(b, 0, 6), 4);
- assert_eq!(a, [3,1,4,1]);
- let mut a = [1,2,3,4];
- let b = ~[5,6,7,8,9,0];
- assert_eq!(a.move_from(b, 2, 3), 1);
- assert_eq!(a, [7,2,3,4]);
- let mut a = [1,2,3,4,5];
- let b = ~[5,6,7,8,9,0];
- assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
- assert_eq!(a, [1,2,6,7,5]);
- }
-
- #[test]
- fn test_copy_from() {
- let mut a = [1,2,3,4,5];
- let b = [6,7,8];
- assert_eq!(a.copy_from(b), 3);
- assert_eq!(a, [6,7,8,4,5]);
- let mut c = [7,2,8,1];
- let d = [3,1,4,1,5,9];
- assert_eq!(c.copy_from(d), 4);
- assert_eq!(c, [3,1,4,1]);
- }
-
- #[test]
- fn test_reverse_part() {
- let mut values = [1,2,3,4,5];
- values.mut_slice(1, 4).reverse();
- assert_eq!(values, [1,4,3,2,5]);
- }
-
- #[test]
- fn test_vec_default() {
- use default::Default;
- macro_rules! t (
- ($ty:ty) => {{
- let v: $ty = Default::default();
- assert!(v.is_empty());
- }}
- );
-
- t!(&[int]);
- t!(@[int]);
- t!(~[int]);
- }
-
- #[test]
- fn test_bytes_set_memory() {
- use vec::bytes::MutableByteVector;
- let mut values = [1u8,2,3,4,5];
- values.mut_slice(0,5).set_memory(0xAB);
- assert_eq!(values, [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
- values.mut_slice(2,4).set_memory(0xFF);
- assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
- }
-
- #[test]
- #[should_fail]
- fn test_overflow_does_not_cause_segfault() {
- let mut v = ~[];
- v.reserve(-1);
- v.push(1);
- v.push(2);
- }
-
- #[test]
- #[should_fail]
- fn test_overflow_does_not_cause_segfault_managed() {
- let mut v = ~[@1];
- v.reserve(-1);
- v.push(@2);
- }
-
- #[test]
- fn test_mut_split() {
- let mut values = [1u8,2,3,4,5];
- {
- let (left, right) = values.mut_split(2);
- assert_eq!(left.slice(0, left.len()), [1, 2]);
- for p in left.mut_iter() {
- *p += 1;
- }
-
- assert_eq!(right.slice(0, right.len()), [3, 4, 5]);
- for p in right.mut_iter() {
- *p += 2;
- }
- }
-
- assert_eq!(values, [2, 3, 5, 6, 7]);
- }
-
- #[deriving(Clone, Eq)]
- struct Foo;
-
- #[test]
- fn test_iter_zero_sized() {
- let mut v = ~[Foo, Foo, Foo];
- assert_eq!(v.len(), 3);
- let mut cnt = 0;
-
- for f in v.iter() {
- assert!(*f == Foo);
- cnt += 1;
- }
- assert_eq!(cnt, 3);
-
- for f in v.slice(1, 3).iter() {
- assert!(*f == Foo);
- cnt += 1;
- }
- assert_eq!(cnt, 5);
-
- for f in v.mut_iter() {
- assert!(*f == Foo);
- cnt += 1;
- }
- assert_eq!(cnt, 8);
-
- for f in v.move_iter() {
- assert!(f == Foo);
- cnt += 1;
- }
- assert_eq!(cnt, 11);
-
- let xs = ~[Foo, Foo, Foo];
- assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
- ~"~[vec::tests::Foo, vec::tests::Foo]");
-
- let xs: [Foo, ..3] = [Foo, Foo, Foo];
- assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
- ~"~[vec::tests::Foo, vec::tests::Foo]");
- cnt = 0;
- for f in xs.iter() {
- assert!(*f == Foo);
- cnt += 1;
- }
- assert!(cnt == 3);
- }
-
- #[test]
- fn test_shrink_to_fit() {
- let mut xs = ~[0, 1, 2, 3];
- for i in range(4, 100) {
- xs.push(i)
- }
- assert_eq!(xs.capacity(), 128);
- xs.shrink_to_fit();
- assert_eq!(xs.capacity(), 100);
- assert_eq!(xs, range(0, 100).to_owned_vec());
- }
-
- #[test]
- fn test_starts_with() {
- assert!(bytes!("foobar").starts_with(bytes!("foo")));
- assert!(!bytes!("foobar").starts_with(bytes!("oob")));
- assert!(!bytes!("foobar").starts_with(bytes!("bar")));
- assert!(!bytes!("foo").starts_with(bytes!("foobar")));
- assert!(!bytes!("bar").starts_with(bytes!("foobar")));
- assert!(bytes!("foobar").starts_with(bytes!("foobar")));
- let empty: &[u8] = [];
- assert!(empty.starts_with(empty));
- assert!(!empty.starts_with(bytes!("foo")));
- assert!(bytes!("foobar").starts_with(empty));
- }
-
- #[test]
- fn test_ends_with() {
- assert!(bytes!("foobar").ends_with(bytes!("bar")));
- assert!(!bytes!("foobar").ends_with(bytes!("oba")));
- assert!(!bytes!("foobar").ends_with(bytes!("foo")));
- assert!(!bytes!("foo").ends_with(bytes!("foobar")));
- assert!(!bytes!("bar").ends_with(bytes!("foobar")));
- assert!(bytes!("foobar").ends_with(bytes!("foobar")));
- let empty: &[u8] = [];
- assert!(empty.ends_with(empty));
- assert!(!empty.ends_with(bytes!("foo")));
- assert!(bytes!("foobar").ends_with(empty));
- }
-
- #[test]
- fn test_shift_ref() {
- let mut x: &[int] = [1, 2, 3, 4, 5];
- let h = x.shift_ref();
- assert_eq!(*h, 1);
- assert_eq!(x.len(), 4);
- assert_eq!(x[0], 2);
- assert_eq!(x[3], 5);
- }
-
- #[test]
- #[should_fail]
- fn test_shift_ref_empty() {
- let mut x: &[int] = [];
- x.shift_ref();
- }
-
- #[test]
- fn test_pop_ref() {
- let mut x: &[int] = [1, 2, 3, 4, 5];
- let h = x.pop_ref();
- assert_eq!(*h, 5);
- assert_eq!(x.len(), 4);
- assert_eq!(x[0], 1);
- assert_eq!(x[3], 4);
- }
-
- #[test]
- #[should_fail]
- fn test_pop_ref_empty() {
- let mut x: &[int] = [];
- x.pop_ref();
- }
-
-
- #[test]
- fn test_mut_shift_ref() {
- let mut x: &mut [int] = [1, 2, 3, 4, 5];
- let h = x.mut_shift_ref();
- assert_eq!(*h, 1);
- assert_eq!(x.len(), 4);
- assert_eq!(x[0], 2);
- assert_eq!(x[3], 5);
- }
-
- #[test]
- #[should_fail]
- fn test_mut_shift_ref_empty() {
- let mut x: &mut [int] = [];
- x.mut_shift_ref();
- }
-
- #[test]
- fn test_mut_pop_ref() {
- let mut x: &mut [int] = [1, 2, 3, 4, 5];
- let h = x.mut_pop_ref();
- assert_eq!(*h, 5);
- assert_eq!(x.len(), 4);
- assert_eq!(x[0], 1);
- assert_eq!(x[3], 4);
- }
-
- #[test]
- #[should_fail]
- fn test_mut_pop_ref_empty() {
- let mut x: &mut [int] = [];
- x.mut_pop_ref();
- }
-}
-
-#[cfg(test)]
-mod bench {
- use extra::test::BenchHarness;
- use iter::range;
- use vec;
- use vec::VectorVector;
- use option::*;
-
- #[bench]
- fn iterator(bh: &mut BenchHarness) {
- // peculiar numbers to stop LLVM from optimising the summation
- // out.
- let v = vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
-
- bh.iter(|| {
- let mut sum = 0;
- for x in v.iter() {
- sum += *x;
- }
- // sum == 11806, to stop dead code elimination.
- if sum == 0 {fail!()}
- })
- }
-
- #[bench]
- fn mut_iterator(bh: &mut BenchHarness) {
- let mut v = vec::from_elem(100, 0);
-
- bh.iter(|| {
- let mut i = 0;
- for x in v.mut_iter() {
- *x = i;
- i += 1;
- }
- })
- }
-
- #[bench]
- fn add(bh: &mut BenchHarness) {
- let xs: &[int] = [5, ..10];
- let ys: &[int] = [5, ..10];
- bh.iter(|| {
- xs + ys;
- });
- }
-
- #[bench]
- fn concat(bh: &mut BenchHarness) {
- let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
- bh.iter(|| {
- let _ = xss.concat_vec();
- });
- }
-
- #[bench]
- fn connect(bh: &mut BenchHarness) {
- let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
- bh.iter(|| {
- let _ = xss.connect_vec(&0);
- });
- }
-
- #[bench]
- fn push(bh: &mut BenchHarness) {
- let mut vec: ~[uint] = ~[0u];
- bh.iter(|| {
- vec.push(0);
- })
- }
-
- #[bench]
- fn starts_with_same_vector(bh: &mut BenchHarness) {
- let vec: ~[uint] = vec::from_fn(100, |i| i);
- bh.iter(|| {
- vec.starts_with(vec);
- })
- }
-
- #[bench]
- fn starts_with_single_element(bh: &mut BenchHarness) {
- let vec: ~[uint] = ~[0u];
- bh.iter(|| {
- vec.starts_with(vec);
- })
- }
-
- #[bench]
- fn starts_with_diff_one_element_at_end(bh: &mut BenchHarness) {
- let vec: ~[uint] = vec::from_fn(100, |i| i);
- let mut match_vec: ~[uint] = vec::from_fn(99, |i| i);
- match_vec.push(0);
- bh.iter(|| {
- vec.starts_with(match_vec);
- })
- }
-
- #[bench]
- fn ends_with_same_vector(bh: &mut BenchHarness) {
- let vec: ~[uint] = vec::from_fn(100, |i| i);
- bh.iter(|| {
- vec.ends_with(vec);
- })
- }
-
- #[bench]
- fn ends_with_single_element(bh: &mut BenchHarness) {
- let vec: ~[uint] = ~[0u];
- bh.iter(|| {
- vec.ends_with(vec);
- })
- }
-
- #[bench]
- fn ends_with_diff_one_element_at_beginning(bh: &mut BenchHarness) {
- let vec: ~[uint] = vec::from_fn(100, |i| i);
- let mut match_vec: ~[uint] = vec::from_fn(100, |i| i);
- match_vec[0] = 200;
- bh.iter(|| {
- vec.starts_with(match_vec);
- })
- }
-
- #[bench]
- fn contains_last_element(bh: &mut BenchHarness) {
- let vec: ~[uint] = vec::from_fn(100, |i| i);
- bh.iter(|| {
- vec.contains(&99u);
- })
- }
-}
+++ /dev/null
-/* This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GCC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#include <rust/rust.h>
-
-void LANG_HOOK(println) (const char * string)
-{
- printf ("%s\n", string);
-}
+++ /dev/null
-/* This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GCC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#include <rust/rust.h>
-
-extern void __rust_main (void);
-
-int main (int argc, char ** argv)
-{
- __rust_main ();
- return 0;
-}